in reply to Invoke sub whose name is value of scalar

my $ref = do { no strict 'refs'; \&$var }; $ref->();

There's usually better ways of achieving one's goals. We could help you better if we knew what you were actually trying to do.

Replies are listed 'Best First'.
Re^2: Invoke sub whose name is value of scalar
by citromatik (Curate) on Apr 14, 2008 at 13:47 UTC
    There's usually better ways of achieving one's goals. We could help you better if we knew what you were actually trying to do.

    I have used symbolic references to simulate linked lists. For example:

    sub _create_node { my ($node,$parent,$node_info) = @_; no strict; @{$node}{qw/parent info/} = ($parent,$node_info); }

    This way, each node is a hash with the name of its parent under the key "parent" and the info related to the node under the key "node_info". To go through a node:

    sub go_through { no strict 'refs'; 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 runs very fast and doesn't need too much memory

    citromatik

      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?

        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