Re: Accessor to module
[email protected] (Eric Wilhelm)
| Newsgroups | perl.moose |
|---|---|
| Message-ID | <[email protected]> |
# from Bianka Martinovic
# on Friday 01 June 2007 01:12 am:
>> You mean the default => sub {} is called whenever an object in that
>> class or a derived class is created? That is by-design.
>
>In fact, I implemented a BUILD method in the loader object and let it
>print a message. It is called when a submodule calls the loader
>accessor. So, yes, I mean that.
Stevan's comment sounds like Moose delays the default attribute creation
until the first time the accessor is called on a given object. That
should be roughly equivalent to what I was saying about object
creation, just that it delays creating the attribute until you actually
use it. Is that about right Stevan?
Point being that the default => sub {} construct is still intended to
instantiate a *new* attribute instance for every object that uses it.
>> You want it to be a singleton that is shared across all objects?
>
>Yes, that's right. I am going to have a base class for my application
>that 'collects' the methods of some helper classes (dynamic module
>loading at runtime, debugging, etc) and provides them to all objects
>that inherit from it. (I know, that's evil...)
>I'm just going to provide a - hm - let's say, a single entry
>point for a bunch of helper modules. I am no aware of a term to
>describe this right, I'm afraid.
I really think the term you want is singleton. That is, there is only
one loader object no matter how many objects are created?
If you want everyone to share the same loader object, then it is a
singleton. Thus, you want "my $loader = CM::Module::Loader->new" ...
"default => $loader". This should basically be doing the same thing as
your sub with the ||=, but without the confusion. (Well, your code
delays creating the loader until it is needed, where this would always
do it when the base class is loaded.)
If CM::Module::Loader->new() always returned the same object, this would
be a classic singleton pattern. You've decided to move that policy one
layer away, but it is still a singleton.
http://en.wikipedia.org/wiki/Singleton_pattern
Constructor:
perl -e '
sub foo {bless({}, "foo")};
print my $x = foo(), "\n";
print my $y = foo(), "\n";
print my $z = foo(), "\n";
'
foo=HASH(0x814cc20)
foo=HASH(0x814ccf8)
foo=HASH(0x814cb3c)
Singleton:
perl -e '
my $foo = bless({}, "foo");
sub foo {$foo};
print my $x = foo(), "\n";
print my $y = foo(), "\n";
print my $z = foo(), "\n";
'
foo=HASH(0x814cc20)
foo=HASH(0x814cc20)
foo=HASH(0x814cc20)
To formalize it a bit, you might do:
package MyLoader;
my $loader;
sub get_loader {$loader ||= CM::Module::Loader->new();}
So, MyLoader->get_loader() always returns the same object. However, if
every subclass inherits the original loader attribute, you only need
the default => $loader lexical closure that I mentioned earlier.
--Eric
--
"Everything should be made as simple as possible, but no simpler."
--Albert Einstein
---------------------------------------------------
http://scratchcomputing.com
---------------------------------------------------