Extend any classes
作者:gugod 發佈於:It may or may not be a good practice / group culture to do this, but it's easy to extend any classes by manipulating the symbol table.
I found myself in love with iterating over things with each
method. Therefore I extend Jifty::DBI::Collection
to add each
on it, I say:
*Jifty::DBI::Collection::each = sub {
my $self = shift;
my $cb = shift;
my $idx = 0;
$self->goto_first_item();
while(my $record = $self->next) {
my $ret = $cb->($record, $idx++, $self);
last if (defined($ret) && !$ret);
}
};
Notice that this needs to be done after use Jifty::DBI
. Then I can do something like this in my Jifty application view code:
PostCollection->each(
sub {
my ($post, $index, $post_collection) = @_;
div { $post->body };
}
);
With the helper function defined in my JiftyX::ModelHelpers
This sometimes gets really handy, and it feels like I'm doing some prototype-based OO in Javascript.
Actually the least scary way to do this is to just use package
twice to switch current package:
package Jifty::DBI::Collection;
sub each { ... };
package main; # Or to wherever you can from.
If you want to avoid two package
calls for some reason, you may use eval
:
eval 'package Jifty::DBI::Collection;
sub each { ... };';
(But then you need to be aware of the quotes.)
I personally found these two approaches are less readable then the symbol table assignment statement above, since I write javascript and ruby code too.
Again, it might not be a good practice. Don't try it at home. Or, try it only if you're at home. ykwim.