代码之家  ›  专栏  ›  技术社区  ›  Evan Carroll

Perl有Andand吗?

  •  4
  • Evan Carroll  · 技术社区  · 16 年前

    我宁愿这样做:

    say $shop->ShopperDueDate->andand->day_name();
    

    与此有关:

    say $shop->ShopperDueDate->day_name() if $shop->ShopperDueDate;
    

    有什么想法吗?

    (这个想法灵感来自红宝石 andand 延伸)

    (事实上,它是受groovy语言的启发,但大多数人不知道这一点;-)

    更新 :我认为maybe()和eval都是很好的解决方案。这不是Ruby,所以我不能期望从左到右读取所有的方法/函数,所以可能肯定会有帮助。当然,eval确实是Perl实现它的方法。

    4 回复  |  直到 16 年前
        1
  •  4
  •   Leon Timmermans    16 年前

    我想我刚刚写好了。我刚上传到CPAN,你可以找到它 here .

        2
  •  9
  •   Ian    16 年前

    您可以使用Perl eval 用于捕获异常的语句,包括那些试图对未定义参数调用方法的语句:

    eval {
        say $shop->ShopperDueDate->day_name();
    };
    

    自从 埃瓦 返回最后一个计算语句,或 undef 失败时,您可以在这样的变量中记录日名称:

    my $day_name = eval { $shop->ShopperDueDate->day_name(); };
    

    如果您真的希望检查异常,可以查看特殊变量 $@ . 这通常是Perl内置异常的简单字符串,但如果异常源于 autodie 或其他使用对象异常的代码。

    eval {
        say $shop->ShopperDueDate->day_name();
    };
    
    if ($@) {
        say "The error was: $@";
    }
    

    也可以使用 埃瓦 块。以下仅检查是否是周末,前提是我们在查找时没有引发任何异常 $day_name .

    eval {
        my $day_name = $shop->ShopperDueDate->day_name();
    
        if ($day_name ~~ [ 'Saturday', 'Sunday' ] ) {
            say "I like weekends";
        }
    };
    

    你可以想到 埃瓦 和…一样 try 来自其他语言;实际上,如果您使用 Error 来自CPAN的模块,然后你甚至可以拼写它 尝试 . 同样值得注意的是,eval的块形式(我已经在上面演示过了)不会带来性能损失,它与其他代码一起编译。的字符串形式 埃瓦 (我还没有展示过)完全是一种不同的动物,如果有的话,应该谨慎使用。

    埃瓦 从技术上讲,它被认为是Perl中的一个语句,因此它是在块末尾看到分号的少数地方之一。如果你不使用的话,很容易忘记这些 埃瓦 有规律地

    保罗

        3
  •  9
  •   Community CDub    7 年前

    我认为你的第二个例子最好是:

    say $shop->ShopperDueDate ? $shop->ShopperDueDate->day_name() : undef;
    

    而不是它实际所说的。

    不管怎样,你不能用 确切地 没有源过滤器的语法是因为 undef 不是对象,而是一元运算符,因此它不能有任何方法。

    相反,考虑一下:

    package noop; 
    our $maybe = bless [], 'noop';
    sub AUTOLOAD { undef };
    

    这个 $noop::maybe 是一个对象;其所有方法都返回 解脱 不过。在其他地方,您将具有这样的常规功能:

    sub maybe { $_[0] || $noop::maybe; }
    

    然后你可以写下:

    say maybe($shop->ShopperDueDate)->day_name()
    

    这是因为“maybe”返回其参数(如果为真),否则返回 诺普:可能 具有始终返回UNdef的方法的对象。

    编辑 更正!这个 ->andand-> 句法 可以 通过使用 XS 这与Perl的内部结构有关。 Leon Timmermans 生成了一个采用此路径的实现。它取代了 undef() 全局函数,所以它可能比我的方法慢很多。

        4
  •  0
  •   ysth    16 年前

    类似(未测试的):

    use Object::Generic::False;
    sub UNIVERSAL::andand { $_[0] || Object::Generic::False->false }
    

    Universal自动是所有其他类的子类,因此它为所有对象提供AndAnd。 (显然,在宇宙中创造方法有可能在遥远的地方发生冲突或惊人的行动, 因此,不应粗心大意地使用它。)如果调用AndAnd方法的对象是真的,则返回它; 否则,将返回一个泛型的false对象,该对象将为对其使用的任何方法调用返回自身。

    推荐文章