Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^2: How to call a sub-routine ref

by grizzley (Chaplain)
on Oct 22, 2012 at 10:14 UTC ( [id://1000305]=note: print w/replies, xml ) Need Help??


in reply to Re: How to call a sub-routine ref
in thread How to call a sub-routine ref

Wow, that looks like magic. Can you please describe why those lines work at all? Or where in perl docs is it explained?

Replies are listed 'Best First'.
Re^3: How to call a sub-routine ref
by Corion (Patriarch) on Oct 22, 2012 at 10:43 UTC

    See the documentation on the arrow operator in perlop.

    Otherwise, the right side is a method name or a simple scalar variable containing either the method name or a subroutine reference, and the left side must be either an object (a blessed reference) or a class name (that is, a package name). See perlobj.

    In the examples, all things on the left hand side return undef, and Perl will call that subroutine reference with the return value. The documentation could be a bit more clear about that undef will also "trigger" that case.

    use strict; use Data::Dumper; my $ref = sub { print Dumper \@_ }; ()->$ref; do{}->$ref; ()->$ref(); do{}->$ref(); __END__ $VAR1 = [ undef ]; $VAR1 = [ undef ]; $VAR1 = [ undef ]; $VAR1 = [ undef ];

      There's actually nothing special about undef. Any scalar will do, including references.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        ... which doesn't make the documentation any less misleading :). I could assume Perl to raise an error if an unblessed reference or a string not specifying a class name appear on the LHS of the arrow operator. Maybe reformulating it as follows makes it match more closely the behaviour:

        Otherwise, the right side is a method name or a simple scalar variable containing the method name, and the left side must be either an object (a blessed reference) or a class name (that is, a package name), see perlobj. As a third case, if the right side is a subroutine reference, the subroutine will be called with the left side unshifted on the parameter list.
Re^3: How to call a sub-routine ref
by tobyink (Canon) on Oct 22, 2012 at 12:33 UTC
    use v5.14; use JSON -convert_blessed_universally; use Test::More; package Foo { sub new { bless \@_ => shift } sub bar { return JSON::to_json(\@_, { convert_blessed => 1, canoni +cal => 1 }) } } package Oof { our @ISA = 'Foo'; sub bar { scalar reverse JSON::to_json(\@_, { convert_blessed => 1 +, canonical => 1 }) } } # You are no doubt familiar with these... my $obj = Foo->new(1); # calling a class method (a constructor) my $str = $obj->bar; # calling an object method is($str, '[[1]]', 'bar returned what we expected'); # Did you know you could do this? my $constructor = 'new'; my $method = 'bar'; $obj = Foo->$constructor(1); $str = $obj->$method; is($str, '[[1]]', 'bar returned what we expected'); # We can even use fully qualified names... $constructor = 'Foo::new'; $method = 'Oof::bar'; $obj = Foo->$constructor(1); $str = $obj->$method; is($str, ']]1[[', 'Oof::bar is the stringy reverse of Foo::bar'); # Or we can use coderefs $constructor = \&Foo::new; $method = \&Oof::bar; $obj = Foo->$constructor(1); $str = $obj->$method; is($str, ']]1[[', 'Oof::bar is the stringy reverse of Foo::bar'); # Now, what is the point of blessing things? We bless objects # so that when we call $object->method, Perl "knows" what # package to find the method in. # # But if we can use coderefs as if they were methods, then # Perl doesn't really need the object to be blessed... # $method = \&Oof::bar; $obj = [1, 2, 3]; # a plain arrayref $str = $obj->$method; is($str, ']]3,2,1[[', 'Can call coderef methods on unblessed things'); # It even works with undef $method = \&Oof::bar; $obj = undef; $str = $obj->$method; is($str, ']llun[', 'llun is null backwards'); # A pair of parentheses evaluates the empty list in list # context, but undef in scalar context. The arrow operator # imposes a scalar context on the left-hand side. $method = \&Oof::bar; $str = ()->$method; is($str, ']llun[', 'llun is null backwards'); # do{} with nothing inside the block returns undef $method = \&Oof::bar; $str = do{}->$method; is($str, ']llun[', 'llun is null backwards'); # More fun... $method = \&Foo::bar; $str = do { my $x = 1; my $y = 2; $x+$y }->$method(2,1); is($str, '[3,2,1]', 'more fun'); # This makes sense when you consider what comma does in scalar context +... $method = \&Foo::bar; $str = (5,4,3)->$method(2,1); is($str, '[3,2,1]', 'maybe counter-intuitive'); done_testing();
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Thanks to you and Corion I have now much to meditate about!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1000305]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-19 12:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found