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'
|