Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Keep It Simple, Stupid
 
PerlMonks

Extending Moose

by zerohero (Monk)
 | Log in | Create a new user | The Monastery Gates | Super Search | 
 | Seekers of Perl Wisdom | Meditations | PerlMonks Discussion | 
 | Obfuscation | Reviews | Cool Uses For Perl | Perl News | Q&A | Tutorials | 
 | Poetry | Recent Threads | Newest Nodes | Donate | What's New | 

on Nov 06, 2009 at 08:49 UTC ( #805427=perlquestion: print w/ replies, xml ) Need Help??
zerohero has asked for the wisdom of the Perl Monks concerning the following question:

I'm relatively new to Moose. I'm trying to add the concept of a cached attribute. Essentially, there is a timestamp that is associated with an attribute, which is checked on each access. If the timestamp is older than a certain threshold, the value gets cleared (by the clearer function), and then the value will automatically be refetched (e.g. from the Database) by the build function.

The code to do the timers and database fetch is very straightforward.

What is less straightforward is the best way to do this in Moose. I have a somewhat reasonable solution, but I'd bet someone will have a far more elegant solution.

My solution works like this: you must declare an "around" method modifier, and pass the name of the attribute to a utility function. The utility function will automatically create a timer associated with the attribute (if needed), as well as reset the timer, and call the clearer method.

It occurs to me that this could be done more cleanly. For one, in the around method I must specify the name of the attribute twice. This allows me to use the same function (named "around_timer_cached" below) generically for all the attributes (note that the around method modifier passes the coderef, but not the attribute, which seems like a flaw). E.g.

around 'some_attribute' => sub { around_timer_cached ('some_attribute' +, @_) };

Is there a more elegant way to get the attribute name in the called "around" method? Also, is there a way to extend the attribute system so that this could just be yet another declarative parameter passed into the "has" decl (e.g. cached_secs => 600).

Finally, has someone already done such extensions to the attribute system?

Comment on Extending Moose
Download Code
Re: Extending Moose
by holli (Monsignor) on Nov 06, 2009 at 19:52 UTC
    package MooseX::CachedAccessor; use 5.008; use Moose::Exporter; use Data::Dumper; use MooseX::Role::Parameterized; Moose::Exporter->setup_import_methods( with_caller => [ 'cache_accessor' ], ); method cache_accessor => sub { my ($caller,$name,%args) = @_; my $code = $caller->can('around'); $code->($name,sub { my $orig = shift; my $self = shift; return $self->{_cache_data}->{$name}->{value} if $self->{_cache_data}->{$name} && $self->{_cache_data}->{$ +name}->{expires} > time; print "fresh\n"; $self->{_cache_data}->{$name}->{expires} = time + $args{expires} +; $self->{_cache_data}->{$name}->{value} = $self->$orig; }); }; 1; ---------------------------------------- package Foo; use Moose; use MooseX::CachedAccessor; has 'bar' => ( is => 'ro', isa => 'Str', default => '' ); cache_accessor 'bar' => (expires => 3); 1; ---------------------------------------- use Foo; my $foo = Foo->new(bar=>'#'); while (1) { print $foo->bar, "\n"; sleep(1); }


    holli

    You can lead your users to water, but alas, you cannot drown them.
[reply]
[d/l]
Re: Extending Moose
by stvn (Monsignor) on Nov 06, 2009 at 23:29 UTC

    You can accomplish all this by extending the attribute system through the meta layer/MOP. You will want to look in Moose::Cookbook::Meta:: to see how this is done. I would also suggest sending a message to the Moose mailing list (or visiting the #moose IRC channel) to see if anyone else has done this.

    -stvn
[reply]

Back to Seekers of Perl Wisdom


Login:
Password
remember me
What's my password?
Create A New User

Node Status
node history
Node Type: perlquestion [id://805427]
Approved by Corion
Front-paged by Arunbear
help
Community Ads
Chatterbox
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users
Others making s'mores by the fire in the courtyard of the Monastery: (11)
GrandFather
wfsp
atcroft
salva
herveus
Eyck
clinton
$self
vishi83
gnosti
eclpmb
As of 2009-11-21 09:42 GMT
Sections
The Monastery Gates
Seekers of Perl Wisdom
Meditations
PerlMonks Discussion
Categorized Q&A
Tutorials
Obfuscated Code
Perl Poetry
Cool Uses for Perl
Perl News
Information
PerlMonks FAQ
Guide to the Monastery
What's New at PerlMonks
Voting/Experience System
Tutorials
Reviews
Library
Perl FAQs
Other Info Sources
Find Nodes
Nodes You Wrote
Super Search
List Nodes By Users
Newest Nodes
Recently Active Threads
Selected Best Nodes
Best Nodes
Worst Nodes
Saints in our Book
Leftovers
The St. Larry Wall Shrine
Offering Plate
Awards
Craft
Snippets Section
Code Catacombs
Quests
Editor Requests
Buy PerlMonks Gear
PerlMonks Merchandise
Planet Perl
Perlsphere
Use Perl
Perl.com
Perl 5 Wiki
Perl Jobs
Perl Mongers
Perl Directory
Perl documentation
CPAN
Random Node
Voting Booth

Future historians will find that the material characteristic of the current era is...

Aluminium
Plastic
Oil
Water
Carbon dioxide
Copper
Iron
Silicon
Salt
Uranium
Hydrogen
Other

Results (729 votes), past polls