Arrow Operator Shenanigans
Out of curiosity, boredom, and some inspiration by the method abuse in Safe::Isa and Object::Remote, I tried the following:
use strict;
use warnings FATAL => 'all';
use feature 'say';
my $split = sub {
my ( $str, $sep ) = @_;
return [ split( $sep, $str ) ];
};
my $join = sub {
my( $arr, $sep ) = @_;
return join($sep,@$arr);
};
say "Lorem ipsum dolor sit amet"->$split(" ")->$join(":");
my $inc = sub {
$_[0]++;
};
my $num = 4;
$num->$inc;
$num->$inc;
say $num;
I was mildly surprised that it worked. I was more surprised that I couldn't find a reason for why it worked in the documentation for the Arrow Operator.
edit [ In the comments I was pointed to perldoc perlobj where this behavior is documented. ]
I'm certain coding this way would be a Pretty Bad Idea ( especially as an undocumented language feature ) but it has a sort of appeal; though 70% of the appeal is just the sheer hackery of it with the rest being some theory that chaining may be easier to read than g(f(x)).
It's documented in 'Subroutine References as Methods' in perldoc perlobj:
so I think it's fine to rely on this behaviour. Might be worth a doc patch for perlop if you had trouble finding the perlobj reference?
Ah very cool, I missed that.
I don't think a doc patch would be neccesary, the link to perlobj is right there, I just failed at finding it.
This is a very useful syntax for dynamic coding, where the subroutine is created at runtime and then passed around.
FYI, Perl6 has sequencer operators for that:
source() ==> filter() ==> sink()
http://perlcabal.org/syn/S03.html
This sound like an interesting way to do reverse auto-boxing, by writing a module that exports a bunch of these methods as scalar variables, thus making it possible to treat a number of common operations as method calls without needing to wrap the basic scalars or messing with UNIVERSAL.
Has somebody written such a module yet?
Seconded!
Mithaldu, People have (ab)used the roles in Moose::Autobox to produce a similar behavior without actual auto boxing.
my $array = bless [] => 'MyArray';
$array->push(1, 2, 3);
print $array->join(", ");
Sometimes when I see stuff like this I start to think perhaps we've not even scratched the surface of what Perl5 syntax can really do, and its just long time practice holding us back.
jnap
Thanks, that's similar and interesting. I have to say though i'm not tempted to use it, since it provides little comfort in use, as i still need to touch and modify each variable i want to call methods on.
Looking at #p5p i find mauke did actually make this: https://metacpan.org/pod/Fauxtobox
What's the reasoning/standard behind the leading underscore in the Fauxtobox methods?
I noticed the same style in Safe::Isa.
Bzzzzzzt. :-) If you failed to find it then chances are that others in your position will make the same assumptions about where to look and then likewise fail to find it. That’s a failure of the docs.
OK, I can give it a shot.
I have no idea. Get on IRC and ask mauke? :)
The leading underscore is probably to reduce the chance of variable name collision, would be my guess. --jnap
i saw that and thought, makes sense. then i wondered why i'd never thought of it.