Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^16: How to completely destroy class attributes with Test::Most?

by nysus (Parson)
on Aug 29, 2019 at 20:52 UTC ( [id://11105264]=note: print w/replies, xml ) Need Help??


in reply to Re^15: How to completely destroy class attributes with Test::Most?
in thread How to completely destroy class attributes with Test::Most?

Ok, I think I might be on to something good...or it could be colossally stupid, I'm not sure which. If I could indulge your attention for a little bit more, I'd appreciate it.

So check this out:

# prints out short name of all "txt-files" $da->bundle_txt_files->do->print_short_names;

And here is the iterator built using your suggestions (I changed the "all" method name to "do," which seemed to make more sense):

package File::Collector::Iterator ; use strict; use warnings; use Carp; use Log::Log4perl::Shortcuts qw(:all); my $collector; # private package variable for storing the Fi +le::Collector sub print_short_names { my $s = shift; print $collector->{files}{$s->selected_file}{short_path} . "\n"; # + uses the File::Collector object to look up short path } sub new { my $class = shift; $collector = shift; # new gets passed the $collector from File: +:Collector AUTOLOAD bless [@_], $class; } sub next { my $self = shift; shift @$self; return $self->[0]; } sub selected_file { (shift)->[0] } # do method of executing methods on child classes sub do { my $self = shift; bless \$self, 'File::Collector::Iterator::All'; } { package File::Collector::Iterator::All; use Log::Log4perl::Shortcuts qw(:all); sub AUTOLOAD { our $AUTOLOAD; my $self = shift; my @method = split /::/, $AUTOLOAD; my $method = pop @method; $$self->$method(@_) while ($$self->next); } }

What do you think? Is this a good solution?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re^17: How to completely destroy class attributes with Test::Most?
by jcb (Parson) on Aug 29, 2019 at 23:07 UTC

    Ideally, the iterator should need no connection to its parent other than shared data, and I see no reason that File::Collector should be a singleton object, which means that it needs to be an instance variable if it is used at all.

    We can avoid that by transferring more data into the newly-constructed iterator. I now see that your application attaches some additional attributes to each file, where I had previously supposed that you care only about the file name. The solution is simple: add a name key to each item in $collector->{files} and change selected_file to:

    sub selected_file { (shift)->[0]->{name} }

    (also change the return value of next)

    When constructing an iterator, pass a list of the relevant entries in ->{files} (which are hashrefs, so the per-category lists should be aliases into the master file set) to new. This even allows another bit of AUTOLOAD magic to provide selected_file_KEY getters that read $self->[0]->{KEY} on an iterator. The explicit selected_file method is therefore an alias for selected_file_name with this approach.

      Ok, but what about the case of a child class of Iterator needing to reach over into another child class with an object attached to one of the attributes? How can my child iterator objects get access to attributes of other child classes if not through File::Collector? Let's say, for example, a File::Collector::Parser::Iterator object needs to get some data from attributes in a File::Collector::HeaderAnalyzer object.

      I suppose I could just pass the File::Collector::HeaderAnalyzer objects to the File::Collector::Parser::Iterator object as a bundle. I'll have to play with this some more and see what I come up with. This is hard!

      Thanks!

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        Every iterator subclass has a corresponding subclass of File::Collector that sorts files into additional categories. I had expected that each subclass that adds attributes ends up adding them to the same hashref as is indexed by $collector->{files}, so that if App::whatever::Collector::HeaderAnalyzer adds an is_valid_header attribute, that attribute appears in $collector->{files}{$filename}{is_valid_header}. Since the iterator now has the entire ->{files}{$filename} hash in its array, the AUTOLOAD magic that I suggested would provide a ->selected_file_is_valid_header method on the iterator object with no actual code in the iterator subclass.

Log In?
Username:
Password:

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

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

    No recent polls found