Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Object methods from hashy structures

by jfrm (Monk)
on Dec 23, 2007 at 22:46 UTC ( [id://658815]=perlquestion: print w/replies, xml ) Need Help??

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

Brothers, for reasons that I won't bore you with I have a big hashy structure thing and now I want to objectify it so that I create a corresponding method for each fieldname. So in my naivety I started writing a method for each key of the hash within my package (class) as follows:
sub status { return $_[0]->{status}; } sub deadline { return $_[0]->{deadline}; } sub chasedate { return $_[0]->{chasedate}; } . . .
When it suddenly occurred to me that if this cannot be how the great God Wall intended things to be. Repetition not being a favourite thing in any PL, let alone PERL. However, I am not too savvy with objects let alone doing clever stuff with subroutines. I'm sure there's an easy answer to eliminating all these methods into a single clever one. Can anyone elucidate?

Replies are listed 'Best First'.
Re: Object methods from hashy structures
by dirving (Friar) on Dec 24, 2007 at 00:50 UTC
    If you want to avoid any external modules, you can do this pretty easily by manipulating the symbol table:
    BEGIN { my @methods = qw/status deadline chasedate/; for my $method (@methods) { no strict 'refs'; # allow symbolic reference *$method = sub { return $_[0]->{$method} }; } }

    There are two tricks here that you might not be familiar with. The first is using the * sigil to manipulate the symbol table. See perldata under the heading "Typeglobs and Filehandles" to learn more about this syntax, and perlmod to learn more about the workings of the symbol table.

    The second trick is the creation of a closure. Using the sub { } notation creates an anonymous subroutine that "closes" over any lexical ("my") variables in the scope where it is defined. You can think of this as attaching the variables to the sub so that it can access them whenever it is called. In this case the sub carries the $method variable with it so that it knows which field of the hash to access when it is called. Search for "closure" in perlref to find out more about these.

    -- David Irving
      That's exactly what I was after, thank you. I appreciate all the enlightening suggestions but implementing new modules was a bit of sledgehammer to crack a nut. A 4 liner is much preferred!
Re: Object methods from hashy structures
by FunkyMonk (Chancellor) on Dec 23, 2007 at 22:51 UTC
    You've got plenty to choose from :( I'd start with Class::Accessor, I think it'll fit your needs.

Re: Object methods from hashy structures
by j1n3l0 (Friar) on Dec 24, 2007 at 00:58 UTC
    Also consider the Moose like so:

    package Foo; use Moose; # define your attributes here ... my %ATTRIBUTES; @ATTRIBUTES{ qw( name age sex job) } = (); # create the accessors here ... for my $attribute ( keys %ATTRIBUTES ) { has $attribute => ( is => 'rw' ); } 1; package main; # assign values to your attributes ... my $foo = Foo->new( name => shift, age => shift, sex => shift, job => shift, ); # access the attributes here ... print join ( q{ }, 'Hi, I am ', $foo->age, 'year old', $foo->name, 'and i work as a', $foo->job, ) . "\n";

    Then execute like so:

    perl t.pl nelo 27 male bioinformatician

    And you get the following:

    Hi, I am 27 year old nelo and i work as a bioinformatician


    Smoothie, smoothie, hundre prosent naturlig!

      Moose actually has a built in feature/shortcut for this.

      package Foo; use Moose; has [qw( name age sex job )] => ( is => 'rw' );
      This will create 4 attributes (name, age, sex, job) in your Foo class, all of which have the same options (is => 'rw').

      -stvn
Re: Object methods from hashy structures
by JStrom (Pilgrim) on Dec 24, 2007 at 02:28 UTC

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-03-28 14:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found