【问题标题】:perl subroutine know if hash is passed or single valuesperl 子例程知道是否传递了散列或单个值
【发布时间】:2014-02-02 20:59:07
【问题描述】:

我正在编写一个 perl 子例程,我希望能够灵活地将值作为散列传递,或者作为单个值传递。我想知道如何将参数传递给子例程,以便我可以分别处理这些情况。例如:

#case 1, pass in hash
test(arg1 => 'test', arg2 => 'test2');

#case 2, just pass in single values
test('test', 'test2');

sub test { 
    #if values passed in as a hash, handle one way
    if(...) { 

    }
    #if values passed in as single values, do something else
    else { 

    }
}

有没有办法在 perl 中检测到这一点?谢谢!

【问题讨论】:

    标签: perl hash arguments subroutine


    【解决方案1】:

    我会使用匿名 HASH 引用做什么:

    #case 1, pass in hash
    test({arg1 => 'test', arg2 => 'test2'});
    
    #case 2, just pass in single values
    test('test', 'test2');
    
    sub test { 
        my $arg = shift;
    
        if(ref $arg eq 'HASH') { 
            ...;
        }
        #if values passed in as single values, do something else
        else { 
             ...;
        }
    }
    


    http://perldoc.perl.org/perlref.html
    http://perldoc.perl.org/perlreftut.html

    【讨论】:

    • 这是一个很好的解决方案!很好的是,如果我愿意,我还可以翻转它并在单个值周围使用散列引用。谢谢!
    • 不确定“围绕单个值”是什么意思?
    • 我会使用if (@_ == 1) 而不是if (ref $arg eq 'HASH')。在 Perl 中检查值的类型通常是错误的,这里也不例外。
    • @ikegami - 实际上我可能两者都做! arg2 可能是可选的,在这种情况下,test('test') 将是一个有效的调用。如果您查看 Moose/Moo 类的构造函数,它们通常会执行类似 if (@_==1 and ref($_[0])=='HASH') { ... } else { ... } 的操作。
    • 你不能用花括号包裹任意标量,因为如果你在奇数位置有两次相同的值,你会丢失参数。因为你会失去秩序,所以你不知道哪个值是哪个参数。因为奇数位置的参数将被转换为字符串。如果您有键值对,则只能使用哈希引用。
    【解决方案2】:

    另一个答案非常好(我已经加分了),但本着 There's More That One Way To Do It™ 的精神,并且为了拉皮条我自己的商品......

    use v5.14;
    use strict;
    use warnings;
    use Kavorka qw( multi fun );
    
    # define a function with positional arguments
    multi fun test (Str $arg1, Str $arg2) {
       say "positional";
       say "\$arg1 is $arg1";
       say "\$arg2 is $arg2";
    }
    
    # define a function with named arguments
    multi fun test (Str :$arg1, Str :$arg2) {
       say "named";
       say "\$arg1 is $arg1";
       say "\$arg2 is $arg2";
    }
    
    # Call the function with positional arguments
    test('foo', 'bar');
    
    # Call the function with named arguments
    test(arg1 => 'foo', arg2 => 'bar');
    
    # Call the function with named arguments again
    test({ arg1 => 'foo', arg2 => 'bar' });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 2011-08-06
      • 2011-02-22
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多