Re: Moose Question

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
Chris,

Actually that code I pasted below has some issues with it, I have  
converted it into an example test in Moose though, so here is the  
corrected (and working) version:

http://code2.0beta.co.uk/moose/svn/Moose/trunk/t/200_examples/ 
008_record_set_iterator.t

- Stevan

On Mar 20, 2008, at 11:38 AM, Stevan Little wrote:
> Chris,
>
> On Mar 19, 2008, at 5:22 PM, Christopher Brown wrote:
>> I do have follow-up questions, though.  Suppose I want to generate  
>> those
>> plain old methods dynamically.  Is there a simple, moose way to do  
>> this in
>> the BUILD subroutine.   On e way to accomplish this is to assign an
>> anonymous subroutine to a glob.  Like this:
>
> The BUILD method runs every time an object is created (per- 
> instance) and by altering the symbol table you are adding a method  
> to the class itself. If the method you add is a closure around a  
> $row (which it seems that is what you are going for) you will only  
> be able to use one instance of this class at a time, otherwise the  
> method you add will override one another.
>
>> package My::App;
>>
>> use Moose;
>> has name => ( is => 'rw', isa=>'Str' );
>>
>> sub BUILD {
>>         **__PACKAGE__::method = sub { print "hello world\n"; } ;*
>> }
>>
>> package main;
>> my $app = My::App->new( { name => 'Moose' } );
>> $app->method;
>>
>>
>> But I don't want to do that.  I want to do it the Moose way.
>
> As I said above, this is not really a good idea, but the Moosey way  
> to do it would be:
>
> sub BUILD {
>     my $self = shift;
>     $self->meta->add_method('method' => sub { ... });
> }
>
> This is documented in Class::MOP::Class.
>
>> I can hear you ask, but why would you want to do that?  Well  
>> suppose, I
>> create an object that wraps a query.  If I can iterate over the  
>> record set I
>> can replace the data slot with the new record and still named  
>> methods that
>> act as accessors to the record.  This beats the snot out of trying to
>> instanciate a row object for each record.
>
> I think, if I understand what you are trying to do correctly, you  
> should do something like this:
>
> (WARNING: this is completely untested code, but it **should** work)
>
> package RecordSetIterator;
> use Moose;
>
> has 'record_set' => (
>     is  => 'ro',
>     isa => 'RecordSet',
> );
>
> # list the fields you want to
> # fetch from the current record
> my @fields = qw[
>     first_name
>     last_name
> ];
>
> has 'current_record' => (
>     is      => 'ro',
>     isa     => 'Record',
>     lazy    => 1,
>     default => sub {
>         my $self = shift;
>         $self->record_set->next() # grab the first one
>     },
>     trigger => sub {
>         my $self = shift;
>         # whenever this attribute is
>         # updated, it will clear all
>         # the fields for you.
>         $self->$_() for map { '_clear_' . $_ } @fields;
>     }
> );
>
> # define the attributes
> # for all the fields.
> has $_ => (
>     is      => 'ro',
>     # make sure they have a clearer ...
>     clearer => ('_clear_' . $_)
>     lazy    => 1,
>     default => sub {
>         my $self = shift;
>         # fetch the value from
>         # the current record
>         $self->current_record->$_();
>     },
> ) for @fields;
>
> sub get_next_record {
>     my $self = shift;
>     $self->current_record($self->record_set->next());
> }
>
>
>
>
>
>
>
>
>
>
>
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.