Why not adopt me?
NAME
rubyisms - Steal some features from Ruby
SYNOPSIS
package Foo;
use rubyisms;
sub initialize { # We inherit a new from class Class
self->{foo} = "bar"; # And we have a receiver, self
__private_stuff(1,2,3,4);
}
sub __private_stuff {
self->{things} = [ @_ ]; # self is still around
self->another_method;
}
sub my_method {
if ($interesting) { ... }
else { super } # Despatch to superclass
}
sub array_iterator (&@) {
yield() for @_;
}
array_iterator { print $_[0], "\n" } ("Hello", "World");
DESCRIPTION
If you can't beat 'em, join 'em. This module exports some functionality to make Perl behave more like Ruby.
Additionally, all classes which use rubyisms
inherit from class Class
, and take a basic new
method from there. (which creates a blessed hash, calls your initialize
method on it and returns it.)
EXPORT
- self
-
This returns the current receiver of methods. This is defined as being the first thing which is-a your class which comes first in some method's
@_
. For instance, in the following case:sub stuff { my ($self, @args) = @_; print self; }
$self
andself
are equivalent here. However, in this case:sub stuff { my ($self, @args) = @_; _more_stuff("Hi!"); } sub _more_stuff { print self }
The
self
in_more_stuff
is equivalent to$self
in its caller: we walk up the stack until we find something that looks like an object we're interested in. If we don't find an object we're interested in, we assume thatself
is the current classs.Obviously you need to be careful with this! Note that
stuff
expects to be called in the usual method call manner, with the object as the first parameter; meanwhile,_more_stuff
expects the receiver to be implicit. Be good and consistent and only use implicit recipients in private methods called from within your class and you'll be all right.
super
When subclassing a class, you occasionally want to despatch control to the superclass - at least conditionally and temporarily. The Perl syntax for calling your superclass is ugly and unwieldy:
$self->SUPER::method(@_);
Especially when compared with its Ruby equivalent:
super;
This module provides that equivalent.
It has been pointed out that using super
doesn't let you pass alternate arguments to your superclass's method. If you want to pass different arguments, well, don't use super
then. D'oh.
yield
yield
provides iterators in Ruby, and now it does so in Perl too. However, in Ruby, methods all take an optional block after their usual arguments. In Perl, we have to fake it. The &
subroutine prototype character allows us to take a block and have it passs in as a coderef, but only if it's the first parameter to a subroutine. For instance, here's how you'd normally code an iterator:
sub each_array (&@) {
my ($coderef, @args) = @_;
for (@args) {
$coderef->($_);
}
}
each_array { print $_[0], "\n" } (10,20,30);
yield
just makes that a tiny bit easier, by working out which is the coderef and calling it with the right thing:
sub each_array (&@) {
yield for @_;
}
yield
will call the coderef with $_
implicitly, or any arguments you give it:
sub each_with_index (&@) {
yield ($_[$_], $_) for 0..$#_;
}
each_with_index { print "The $_[1]th element is $_[0]\n" } @stuff;
Note that this doesn't actually modify @_
: the coderef is still $_[0]
, but yield
attempts to avoid yielding onto itself. That is to say, yield
does nothing when the first argument passed is the same as the coderef itself.
If you actually do want to call the coderef on itself, i) you're weirder than I am, and ii) call it as something other than the first argument:
yield ("dummy", $_) for @_;
will happily pass the coderef in.
NOTE
The module tries to do the right thing in all cases, and it does do the right thing in the vast majority of cases. But like all labour-saving devices, you give up a little bit of control to gain a bit of convenience. So maybe it'll do the wrong thing in pathological cases. Consider it karmic retribution.
SUPPORT
Beep... beep... this is a recorded announcement:
I've released this software because I find it useful, and I hope you might too. But I am a being of finite time and I'd like to spend more of it writing cool modules like this and less of it answering email, so please excuse me if the support isn't as great as you'd like.
Nevertheless, there is a general discussion list for users of all my modules, to be found at http://lists.netthink.co.uk/listinfo/module-mayhem
If you have a problem with this module, someone there will probably have it too.
AUTHOR
Simon Cozens, simon@cpan.org
SEE ALSO
ruby(1)
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 171:
You forgot a '=back' before '=head2'