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
---------------------------------------------------
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.