in reply to Re^5: Invoke sub whose name is value of scalar
in thread Invoke sub whose name is value of scalar

Sorry, I don't get it

I suppose I'm really wrong seeing the number of downvotes my post is accumulating, but I can't see your solution.

I'm using this technique in a script that has to process a big number of lists. The symbolic link strategy is significantly faster than the hash-based solution and occupies less system memory.

But, again, I can't see your solution. could you develop it a little more, please?

citromatik

  • Comment on Re^6: Invoke sub whose name is value of scalar

Replies are listed 'Best First'.
Re^7: Invoke sub whose name is value of scalar
by dragonchild (Archbishop) on Apr 14, 2008 at 16:02 UTC
    The reason you're using symbolic references is because you're passing a string in. If you pass in a reference to a hash (aka, hashref), then you stop using a symbolic reference and you start using a hash reference.

    As for speed, you're completely and utterly wrong. Symbolic references ARE hashes. The hash being used is the symbol table. It actually uses MORE memory because of how the symbol table is implemented.

    Did you actually try my suggestions? Or, did you just read them and go "I don't get it."?


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Did you actually try my suggestions? Or, did you just read them and go "I don't get it."?

      Yes, I tried your suggestions. I'm really interested in knowing how you would solve the problem, but with your indications I didn't get it:

      Remove the no strict 'refs'; in both subroutines and try the following: ...
      my $root = {}; _create_node ($root,"pp1","first"); _create_node ($root->{pp1},"ppp1","second"); _create_node ($root->{ppp1},"pppp1","third"); _create_node ($root->{pppp1},"ppppp1","root"); my $infos = _go_through('p1'); #my $infos = _go_through($root); # doesn't work either print Dumper $infos; sub _create_node { # no strict 'refs'; my ($node,$parent,$node_info) = @_; @{$node}{qw/parent info/} = ($parent,$node_info); } sub _go_through { my ($node) = @_; return "" unless defined ${$node}{"info"}; my @info_nodes; while (${$node}{"info"} ne "root"){ push @info_nodes, (${$node}{"info"}); $node = ${$node}{"parent"}; ## Line 33 } return \@info_nodes; }

      This doesn't work:

      Can't use string ("pp1") as a HASH ref while "strict refs" in use at ... line 33

      Obviously, I'm missing something, that is why I asked

      citromatik

        Oh. I see the problem and why I didn't see it before. Your problem is that you're mixing data structures. Try the following version of _create_node and _go_through:
        _create_node ('p1',"pp1","first"); _create_node ('pp1',"ppp1","second"); _create_node ('ppp1',"pppp1","third"); _create_node ('pppp1',"ppppp1","root"); my $infos = _go_through('p1'); print Dumper $infos; { my %nodes; sub _create_node { my ($node_id,$parent,$node_info) = @_; @{$nodes{$node_id}}{qw/parent info/} = ($parent,$node_info); } sub _go_through { my ($node_id) = @_; return "" unless defined ${$nodes{$node_id}}{"info"}; my @info_nodes; while (${$nodes{$node_id}}{"info"} ne "root"){ push @info_nodes, (${$nodes{$node_id}}{"info"}); $node_id = ${$nodes{$node_id}}{"parent"}; ## Line 33 } return \@info_nodes; } }
        I actually tested this code. :-)

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
        You need to adjust your syntax, try:
        $node = $node->{"parent"}; ## Line 33

        Update: this is incorrect, please ignore.

Re^7: Invoke sub whose name is value of scalar
by Jenda (Abbot) on Apr 14, 2008 at 19:42 UTC

    I think you should show us an example of those lists and what do you need to do with them and I bet we can suggest a solution that will use significantly less memory and will be quicker than your symbolic references. Do not use symbolic references! Ever.