in reply to How to detect a hash container key from a referenced sub value

So, the question, as I mentioned above and as you saw in the sub, how does the subroutine know it's container hash key, in order to calculate the right key's qty values?

Various ways.

As a rule of thumb - if you ask yourself how does X know it's Y, the object approach suits best.

Replies are listed 'Best First'.
Re^2: How to detect a hash container key from a referenced sub value
by igoryonya (Pilgrim) on Dec 04, 2009 at 06:39 UTC
    Hello, so to summarize everything, I've learned a few things:
    1. I learned that in order to use aware functions on complex variables, it's better to use objects with methods.
    2. I learned that packages can be in the same file as the main script.
    3. I learned that bless function makes methods work in objects.
    One thing that confused me in bless function was the way it was written:
    bless { @_ }, $class;
    I couldn't understand it, forgetting that functions can be used without parentacies (I sined myself, doing that) and arrays can be applied and converted to hashes that way.

    Then, after digesting all of the information, you guys gave me and taking a closer look, I've had a revelation that { @_ } is nothing other then a regular anonymous hash reference of @_ array being converted to hash ref by {} braces and a $class is a reference to Self object.

    So, not exactly, but in other words:
    my %hash = @_; bless(\%hash, $selfObjRef);
    or
    bless({@_[1..$#_]}, $_[0]);
    One thing I am a little confused still is, when I add values to the variable this way:
    my %phrases = ( "phrase 1" => Qty->new( qty => 1, qtySum => 5, qtyCont => 8 ), "phrase 2" => Qty->new( qty =>10, qtyCont =>34 ), "phrase 3" => Qty->new( qty =>1 ) );
    Can I still access them by (I didn't test it yet, still trying to digest everything)?:
    print $phrases{'phrase 2'}->{'qtySum'}; print $phrases{'phrase 1'}->{'qtyCont'}; print $phrases{'phrase 3'}->{'qty'};
    I thought about coding the way, you've described in your first 2 methods with closures before posting to perlmonks, but things that stopped me were a curiosity if it's possible to do it without passing parameters, informing about it's container to a function and also I needed the function to be able to accept explicit parameters, because I do not always need a total of all qtys. Sometimes, I would need a total of qty and qtyCont and sometimes, a qty and qtySum, etc..

    You guys've made a point that it's done with objects, and I need to read more to understand them better and experiment a little bit.

    While reading, your first 2 methods, I remembered of using static variables in regular subs, which, in turn made me think about ability to pass explicit values without polluting them with container info to an anonymous sub, which passes all of the values to the sub, calculating qtys.

    my %phrases = ( 'phrase 1'=>{ qty=>1, qtySum=>5, qtyCont=>8, qtyTotal=>sub{return &qtyTotal('phrase 1', @_);} }, 'phrase 2'=>{ qty=>10, qtyCont=>34, qtyTotal=>sub{return &qtyTotal('phrase 2', @_);} }, 'phrase 3'=>{ qty=>1, qtyTotal=>sub{return &qtyTotal('phrase 3', @_);} } );
    I've used a key value, but I understand, that the current branch reference can also be used.

    I realize, that this is an inefficient solution, but this is the solution that allows using pseudo methods without an actual objects.

    I need to play some more with objects to completely grasp the subject, while the pseudo method is a temporary solution, until I completely understand objects and update my program to use objects instead.

    Thank You all for your help.

      Then, after digesting all of the information, you guys gave me and taking a closer look, I've had a revelation that { @_ } is nothing other then a regular anonymous hash reference of @_ array being converted to hash ref by {} braces and a $class is a reference to Self object.

      No, not quite. See "Method Invocation" in perlobj. For class methods, the first argument for a method is the class (just its name); for objects, it is the object. Not a reference - just like that. For class methods, the class name is a literal, and the object is a reference already. The arrow operator "->" makes the passing of the first parameter implicit, so the next two are equivalent:

      $obj = MyClass->new( %params); $obj = MyClass::new( 'MyClass', %params);
      Can I still access them by (I didn't test it yet, still trying to digest everything)?:

      Yes, since an object is just a reference blessed into a Namespace. Otherwise, it behaves just like any reference. Again, read perlobj and related material.

      qtyTotal=>sub{return &qtyTotal('phrase 1', @_);}

      I realize, that this is an inefficient solution, but this is the solution that allows using pseudo methods without an actual objects.

      The use of the ampersand "&" as a sigil to suroutine calls makes passing @_ implicit, but only if the call has an empty parameter list. Consider:
      $\ = $/; # see perlvar sub b { print join" ",@_ } sub e { &b } # @_ passed implicitly sub f { &b( "got") } # parens necessary! sub g { b "got", @_ } # parens may be omitted, if sub b # has been seen earlier @l = (1...3); e @l; f @l; g @l; __END__ 1 2 3 got got 1 2 3

      So, use "&" only if you mean to pass @_ (and only @_) implicitly.

      And it's not ineffective, I'd say, but neither is it "pseudo-methods" - that is calling anonymous subroutines. A pseudo method (call) would be something like the following:

      sub b { print join" ", @_ } "b"->(1..3)

      Further reading: perlboot, perlref, perlreftut, perltoot, ...

        I got it. Thanx.
        And it's not ineffective, I'd say,
        By inefficient, I mean that I have to iterate through all of the keys to add that sub with the key or a reference to the container manually, but I figure that object does it automatically. Again, I understand that I still need to read perl object tutorials, so I might be wrong at something yet.
        @l = (1...3);
        I guess, this is?
        @l = (1..3);
        or it's some operator that I am not aware of?