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

Except that's not a symbolic reference. That's a hash-reference and your code is more commonly written as:
sub go_through { my ($self, $node) = @_; return unless defined $node->{info}; my @info_nodes; while ( $node->{info} ne 'root' ) { push @info_nodes, $node->{info}; $node = $node->{parent}; } return \@info_nodes; }
This version also fixes a bug you had in your original code regarding contexts.

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?

Replies are listed 'Best First'.
Re^4: Invoke sub whose name is value of scalar
by citromatik (Curate) on Apr 14, 2008 at 15:16 UTC

    I don't know if you have understand correctly my snippet. Here is a working example to clarify:

    use strict; use warnings; use Data::Dumper; _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; sub _create_node { my ($node,$parent,$node_info) = @_; no strict 'refs'; @{$node}{qw/parent info/} = ($parent,$node_info); } sub _go_through { no strict 'refs'; my ($node) = @_; return "" unless defined ${$node}{"info"}; my @info_nodes; while (${$node}{"info"} ne "root"){ push @info_nodes, (${$node}{"info"}); $node = ${$node}{"parent"}; } return \@info_nodes; }

    Outputs:

    $VAR1 = [ 'first', 'second', 'third' ];

    We can argue if this use of symbolic references is a correct strategy or not, but I hope that we agree that they ARE symbolic references

    Your subroutine using the arrow notation works as well, excepts that you need to switch off strict-ness:

    sub _go_through { no strict 'refs'; my ($node) = @_; return unless defined $node->{info}; my @info_nodes; while ( $node->{info} ne 'root' ) { push @info_nodes, $node->{info}; $node = $node->{parent}; } return \@info_nodes; }

    Or you will get pretty

    Can't use string ("p1") as a HASH ref while "strict refs" in use at .. +.

    citromatik

      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' ); # And so forth

      You were forcing your code to use symbolic references. Intrinsically, it wasn't doing so. In other words, the code didn't look like it forced the use of symbolic references. It was only your usage of it that was forcing it to do so. And, by doing it my way, you will avoid some really nasty, hard-to-find bugs.


      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?

        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