Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Loop though class attributes

by ZX81Meister (Initiate)
on Feb 24, 2018 at 07:02 UTC ( [id://1209884]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there, I've just discovered the means of OOP in Perl and got a newbie question... I've defined a class with attributes like this:

sub new { my $class = shift; my $s = {}; bless $s, $class; $s->{Laboratory} = new MotionSensorB('Laboratory', 'senMotion_H2_S1 +'); $s->{Fruitcellar} = new MotionSensorA('Fruitcellar', 'senMotion_H1_S1 +'); return $s; }

In the same package I want to loop through the attributes, that is, access the elements Laboratory and Fruitcellar:

sub event { my $c = shift; foreach my ??? (???) { print ??? . "\n"; }

I'm not so firm with arrays, hashes, references etc. and trying all sorts of combinations, but can't get it right. How can I achieve it?

Replies are listed 'Best First'.
Re: Loop though class attributes
by Corion (Patriarch) on Feb 24, 2018 at 07:17 UTC

    Since your object is still mostly just a hash, you can iterate over its keys:

    sub event { my $c = shift; foreach my $key (keys %$c) { print $key . "\n"; } }

      That's a little more efficient than the solution I came up with, give thx!

      foreach my $o (%{$c}) { if(ref(\$o) eq 'REF' && exists($o->{Device}) && $o->{Device} eq $dev +ice) { $o->motion; last; } }

        If you are just going to literally iterate over the structure of your object, you really should be doing some checking to ensure each value is an object you can act upon. Personally, if I were to do something like this, I'd make a sensors top-level key, and stuff the sensors in there. That way, all sensor objects are within a single location. This allows greater flexibility going forward.

        Either way, UNIVERSAL::can is a decent, clean way to see if a) the value of each key is indeed an object, and b) checks whether it can perform a specific task:

        use warnings; use strict; package Device; { sub new { my $self = bless {}, shift; $self->{s1} = Sensor->new; $self->{s2} = Sensor->new; $self->{s3} = "string"; return $self; } sub event { my ($self) = @_; for (keys %{ $self }){ if (UNIVERSAL::can($self->{$_}, 'motion')){ print "yep, '$_' is a sensor object\n"; } else { print "'$_' isn't a damned sensor!\n"; } } } } package Sensor; { sub new { return bless {}, shift; } sub motion { ... } } package main; my $device = Device->new; $device->event;

        Output:

        yep, 's1' is a sensor object 's3' isn't a damned sensor! yep, 's2' is a sensor object
Re: Loop through class attributes
by choroba (Cardinal) on Feb 24, 2018 at 21:12 UTC
    Higher level frameworks like Moose provide means to access attributes through meta-programming:
    #!/usr/bin/perl use warnings; use strict; sub MotionSensorA::new { bless { type => $_[1] }, $_[0] } sub MotionSensorB::new { bless { type => $_[1] }, $_[0] } { package Device; use Moose; has laboratory => (is => 'ro', isa => 'MotionSensorB', default => sub { 'MotionSensorB'->new('senMotion_H2_S1'); }); has fruitcellar => (is => 'ro', isa => 'MotionSensorA', default => sub { 'MotionSensorA'->new('senMotion_H1_S1'); }); sub event { my ($self) = @_; foreach my $device ($self->meta->get_attribute_list) { print "$device: ", $self->$device->{type}, "\n"; } } __PACKAGE__->meta->make_immutable; } my $d = 'Device'->new; $d->event;
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-18 03:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found