in reply to Automatic vivification of an object

The basic idea is that instead of creating an instance of a class, you would create an instance of the autovivifying class that calls an initialization function the first time it needs to

This smakes of a solution looking for a problem.

Two questions:

  1. Why would I instantiate an instance of a class that I'm not going to use?

    Smacks of a bad cure for a bad scoping problem; better corrected by correctly scoping the instantiation.

  2. In what scenario is there a benefit in deferring the instanciation from where I declare the instance, to the point of first use?

    Quantify the benefit.

A third question: Why does your "example of usage" not actually run?

C:\test>t-autoVivify.pl Can't locate object method "new" via package "autovivify" (perhaps you + forgot to load "autovivify"?) at C:\test\t-autoVivify.pl line 29.

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

Replies are listed 'Best First'.
Re^2: Automatic vivification of an object
by bounsy (Acolyte) on Jan 14, 2015 at 03:59 UTC
    1. The reason I came up with this was actually because I was looking for a solution to a specific code problem that I have. I have a class that is part of an inheritance tree of classes (in the middle) that needs to have an instance of that class as a shared variable (declared using "our"). It also needs to have access to variables declared in other classes in the tree. Because of the way the inheritance is working out, I'm having difficulty finding a way to handle this without delayed initialization. And, instead of coming up with a class-specific solution, I was trying to come up with a generic solution.
    2. I think I already answered this in #1, above.
    3. It was extracted from the code I had been using to play around with the concepts. I've modified the example usage and it should work now. (I added the "use AutoVivify;" line and corrected the case on the line where a new instance is being created.)
      I have a class that is part of an inheritance tree of classes (in the middle) that needs to have an instance of that class as a shared variable (declared using "our"). It also needs to have access to variables declared in other classes in the tree. Because of the way the inheritance is working out, I'm having difficulty finding a way to handle this without delayed initialization.

      Then you are fixing the symptoms of the problem rather than the problem itself.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Quite possibly.

        The basic class hierarchy I'm working with makes good design sense and is essentially a tree of classes with one base class that is subclassed one or more times, each of those is subclassed zero or more times, plus another layer or two of subclasses beyond that on some branches. Currently there is no multiple inheritance (though I don't think I can completely rule that out for the future). I also can't rule out the possibility that the base class won't someday be a subclass of another class (such as a standard Perl class of some kind).

        Each class in the hierarchy has a hash variable that contains a set of values that add to and/or overload the same set of values from the parent class. I'd like to have a function in the parent class that creates a merged hash and caches that value (on the first call) or returns the cached value (on subsequent calls). I'd rather not copy a lot of code to each class to do the merging and caching in each class.

        I have the above working just fine when called at runtime, but if I try to create an instance of the base class as part of module compilation (i.e., my $obj = classname->new(...) code outside of any sub declaration, not using a BEGIN block), it doesn't work. (I suspect it has something to do with the order in which variables are declared and/or initialized.) Hence, I am changing it to create the required object the first time it needs it rather than at compile time.

        As this is a one-time step, any costs involved in eval (which I've now removed because it wasn't needed) or autoload is negligible in this case. Even so, I'm trying to minimize the impact so that I can use this as a generalized auto-vivification and/or delayed initialization solution in the future.

      Although I don't want to discourage the development of a solution if it works, is tested, and is useful, I tend to agree that it sounds like your problem might have a more direct solution, by updating the OO design. If a parent class needs access to a subclass's property, an abstract accessor is a solution, and if a subclass needs access to a parent, then an accessor should do. As for a class offering an instance of itself, maybe a short example would help to see what you're doing. Maybe there is some other thing that could be delayed from initialization time to runtime whose solution would come more naturally.

        The problem is not how to get to the data. The problem is when to get to the data. Even with accessors and abstract accessors, I need to defer until compilation of the modules is complete before I try to use the accessors. That's why I was looking for a way to defer initialization and came up with the automaic vivification method I started with.