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());
> }
>
>
>
>
>
>
>
>
>
>
>
>
>
>