Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Perl's equivalent to Python's hasattr and getattr? (class variable details)

by MistaMuShu (Beadle)
on Jul 28, 2005 at 23:19 UTC ( [id://479170]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all,

I'm starting to learn about Perl objects and having trouble understanding the internal workings. As I understand it, instance variables are stored in the "referenced thingy". But how does Perl do class variables? Since a 'class' is a package, is it correct to say that variables local to a package are "class variables"?

package Thing; my $class_var = 1; sub new { return bless {}, "Thing"; } sub set_class_var { $class_var = $_[0]; } 1;

I tried this out and it seems to make sense, but I hope someone can rephrase this more articulately. The other question I have concerns how class variables are stored. I want to have a single "set" method to change class variables rather than one per variable. Something along the lines of:

sub set { my $self = shift; my %args = @_; while( my ($var, $val) = each %args ) { #if $var is defined #set class_variable var to $val } }

In Python, I could use hasattr, getattr, and setattr to accomplish this. What's the Perl style to do it?

I apologize in advance if I blurted out any rubbish or missed something searching around. Any interesting beginner links to closures, Perl object internals, and symbol tables would also be cool. I'm in the process of reading the ones in the tutorial section, but still struggling through it somewhat. Thanks all in advance.

Replies are listed 'Best First'.
Re: Perl's equivalent to Python's hasattr and getattr? (class variable details)
by Ovid (Cardinal) on Jul 28, 2005 at 23:51 UTC

    Regrettably, Perl does not have a clean distinction between classes and instances of said classes. As a result, class data is something that folks tend to forget about. One way of creating your set method is to store your class data in a hash.

    my %CLASS_DATA = (...); sub set { my ($self, %args) = @_; while (my ($var, $val) = each %args) { if (exists $CLASS_DATA{$var}) { $CLASS_DATA{$var} = $val; # whoops! No validation } else { # create the var, croak, etc. } } }

    If you don't like the validation, you could have each value in %CLASS_DATA be a sub ref that points to the real setter.

    Personally, I've enjoyed Class::MethodMaker to handle much of this for me, though the recent test failures are disheartening.

    Cheers,
    Ovid

    New address of my CGI Course.

Re: Perl's equivalent to Python's hasattr and getattr? (class variable details)
by rlb3 (Deacon) on Jul 28, 2005 at 23:29 UTC
    Hello,

    I think you may want something like Class::Accessor. Class::Accessor is just one of many modules that may work for you. You may want to look at the Class:: namespace in the cpan.

      Wow, that hits it right on the spot! I find it weird that this isn't builtin. Maybe I'll skim through and look up how Class::Accessor is implemented. Is it possible to do something similar theorically by manipulating symbol tables?

        Class::Accessor is built using the symbol table. Here is the _mk_accessors as an example.

        { no strict 'refs'; sub _mk_accessors { my($self, $maker, @fields) = @_; my $class = ref $self || $self; # So we don't have to do lots of lookups inside the loop. $maker = $self->can($maker) unless ref $maker; foreach my $field (@fields) { if( $field eq 'DESTROY' ) { require Carp; &Carp::carp("Having a data accessor named DESTROY in +". "'$class' is unwise."); } my $accessor = $self->$maker($field); my $alias = "_${field}_accessor"; *{$class."\:\:$field"} = $accessor unless defined &{$class."\:\:$field"}; *{$class."\:\:$alias"} = $accessor unless defined &{$class."\:\:$alias"}; } } }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-06-20 22:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.