Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Automagic subroutines

by rje (Deacon)
on Jan 03, 2005 at 23:25 UTC ( [id://419095]=perlquestion: print w/replies, xml ) Need Help??

rje has asked for the wisdom of the Perl Monks concerning the following question:

Brothers and Sisters in Perl,

I've discovered the magic of eval(), but I suspect TABWTDI (There's A Better Way To Do It). Behold my scary-but-cool perl module.

It works like this: when a new object is created, the user also specifies the attributes of the object. Cool, eh? The new() method dutifully then builds some eval() statements which automagically create a getter-setter method for each attribute, using that attribute's name as the method name. Scary, eh?

Y'all might have done this already, but it was a fun and startling revelation for me.
package TEST; use strict; ############################################## # # A generic object with fields specified # at creation time. # ############################################## my %data; sub new { my $self = bless [], shift; my @required_fields = @_; foreach my $field (@required_fields) { chomp $field; my $eval = "sub $field : lvalue { \$data{+shift}->{$field}; }"; eval $eval; } return $self; } sub DESTROY { delete $data{+shift}; } 1;
I can now do neato things like this:
my $test = new TEST qw( foo bar baz ); $test->foo = 3; $test->bar = "Boy is this a messed-up object!"; $test->baz = "I bet someone else has a better way to do this.";
-Rob

Replies are listed 'Best First'.
Re: Automagic subroutines
by borisz (Canon) on Jan 03, 2005 at 23:40 UTC
Re: Automagic subroutines
by osunderdog (Deacon) on Jan 04, 2005 at 00:07 UTC

    This technique is very useful. It's discussed in perltooc.

    perldoc perltooc

    Going out on a limb here but personally I don't use this technique as I feel that it makes it difficult to see the accessors that are created. I would probably lean toward Class::Accessor too.


    "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.

Re: Automagic subroutines
by revdiablo (Prior) on Jan 04, 2005 at 01:13 UTC

    I'm not quite sure how to make these lvalues, but you can generate accessor/mutator methods without using eval. Here's a quick example:

    foreach my $field (@required_fields) { no strict 'refs'; chomp $field; *$field = sub { my $self = shift; if ($_[0]) { $self->{$field} = $_[0]; } else { $self->{$field); } }; }

    Note: I am not necessarily endorsing this type of hybrid mutator/accessor, just using it as an example.

Re: Automagic subroutines
by Limbic~Region (Chancellor) on Jan 04, 2005 at 16:54 UTC
    rje,
    As others have pointed out, there are already modules that do this. As revdiablo pointed out, there are ways to avoid using eval to dynamically create subs and this fully functional example allows them to be lvaluable.
    package Cool; use strict; use warnings; sub new { my $class = shift; my $self = bless {}, $class; $self->_Init( @_ ); return $self; } sub _Init { my $self = shift; { no strict 'refs'; for my $method ( @_ ) { *{ $method } = sub :lvalue { $_[0]->{$method} }; } } } "That's cool man";
    And here is a script that uses it:
    #!/usr/bin/perl use strict; use warnings; use Cool; my $obj = Cool->new( qw(foo bar baz) ); $obj->bar = "A better way of doing this"; print $obj->bar, "\n";

    Cheers - L~R

      Thanks LR!

      These are great counter-examples, because they give me a much-needed introduction on using typeglobs... which is something I've never used before.

      You guys are helping me understand Perl better. As well as giving me some good CPAN references. Thanks and keep up the good work!

      Rob
Re: Automagic subroutines
by Courage (Parson) on Jan 04, 2005 at 13:34 UTC
    looks like there's no question there, may be you mean to post in meditation section??

Log In?
Username:
Password:

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

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

    No recent polls found