Re: Function name in a variable, can't recall the concept
by haukex (Archbishop) on Apr 02, 2019 at 14:29 UTC
|
#!/usr/bin/env perl
use warnings;
use strict;
sub somefunc { print "Hello, $_[0]\n" }
my %dispatch = (
foo => \&somefunc,
bar => sub { print "World$_[0]\n" },
);
$dispatch{foo}->("Perl");
$dispatch{bar}->("!");
#!/usr/bin/env python3
def somefunc(x):
print("Hello, "+x)
dispatch = {
'foo': somefunc,
'bar': lambda x: print("World"+x),
}
dispatch["foo"]("Perl")
dispatch["bar"]("!")
Note however that using a string as a reference is a symbolic reference and is generally discouraged (and generally not possible under strict): Why it's stupid to `use a variable as a variable name'. Usually it's better to use a hash instead, like the above %dispatch. Update: And your second example is probably better written as my $funcname = ( $someCondition ? \&foo : \&bar ); | [reply] [d/l] [select] |
Re: Function name in a variable, can't recall the concept
by tybalt89 (Monsignor) on Apr 02, 2019 at 14:50 UTC
|
#!/usr/bin/perl
# https://perlmonks.org/?node_id=1232013
use strict;
use warnings;
my $someCondition = 0;
my $arg1 = 'arg1';
my $arg2 = 'arg2';
my $funcname = ( $someCondition ? 'foo' : 'bar' );
SomeClass->$funcname($arg1, $arg2);
package SomeClass;
sub foo { print "in 'foo' with args: @_\n" }
sub bar { print "in 'bar' with args: @_\n" }
| [reply] [d/l] |
Re: Function name in a variable, can't recall the concept
by Eily (Monsignor) on Apr 02, 2019 at 14:27 UTC
|
perl -E "use strict; use warnings; sub hello { say 'Hi' }; my $sub = '
+hello'; $sub->()"
Can't use string ("hello") as a subroutine ref while "strict refs" in
+use at -e line 1.
So if your Pythonista were to look into it, he would find a lot of "Don't do that!" | [reply] [d/l] |
|
\&$sub_name
This means that while
$sub_name->()
isn't allowed,
(\&$sub_name)->()
is allowed.
($invocant->$method_name() is also allowed under strict.) | [reply] [d/l] [select] |
|
| [reply] |
|
> However, there is an exception:
More there are:
use strict;
use warnings;
sub tst {
warn "tst($_[0]) called\n"
}
my $symbol="tst";
($::{$symbol})->(1);
&{$::{$symbol}}(2);
(main->can($symbol))->(3);
&{main->can($symbol)}(4);
C:/Perl_524/bin\perl.exe d:/exp/symbolic_references.pl
tst(1) called
tst(2) called
tst(3) called
tst(4) called
NB:
$::{...} is a shortcut for STASH lookup $main::{...} and returns a type-glob
->can(...) returns a coderef
| [reply] [d/l] [select] |
|
|
|
|
use strict;
use warnings;
sub asub { print "heee\n"; }
my $x = 'asub';
main->$x();
bw, bliako | [reply] [d/l] |
|
| [reply] [d/l] [select] |
|
|
|
|
Re: Function name in a variable, can't recall the concept
by mpersico (Monk) on Apr 02, 2019 at 15:00 UTC
|
Today is not my day.
When it was mentioned that what I demonstrated in my examples wouldn't work under use strict; I went back and looked at the code again and realized my example was wrong. Here's what I am really doing:
my $funcname = ( $someCondition ? 'foo' : 'bar' );
$someObject->$funcname($arg1, $arg2);
It's not "Function name in variable", it's "Method name in variable", and a relevant reference to same is https://perldoc.perl.org/perlobj.html#Method-Call-Variations
| [reply] [d/l] [select] |
|
use strict;
use warnings;
package Object;
sub new { return bless \{} }
sub foo { printf "hello foo = %s\n", ( caller(0) )[3]; }
sub bar { printf "hello bar = %s\n", ( caller(0) )[3]; }
package main;
my $someObject = Object->new();
my $someCondition = 0;
my $funcname = ( $someCondition ? 'foo' : 'bar' );
$someObject->$funcname($funcname);
$someCondition = 1;
$funcname = ( $someCondition ? 'foo' : 'bar' );
$someObject->$funcname($funcname);
| [reply] [d/l] |
Re: Function name in a variable, can't recall the concept
by mpersico (Monk) on Apr 02, 2019 at 14:48 UTC
|
Lovely.
The code has use strict; use warnings; in it and I don't recall it failing its tests, so now, not only do I have to admit to the Pythonista that I did a Bad Perl Thing, I have to figure out why the code coverage is bad.
The heck with it. I ain't admitting nothing. I've already coded my way out of it because the two conditions I was dealing with need distinct messages so I am just going to use an if/else and move on.
Thank you, all. | [reply] [d/l] [select] |
Re: Function name in a variable, can't recall the concept (introspection with ->can )
by LanX (Saint) on Apr 14, 2019 at 14:16 UTC
|
If you want to appease your supervisor use UNIVERSAL::can()
my $func_name = ( $someCondition ? 'foo' : 'bar' );
my $func_ref = __PACKAGE__->can($func_name); # or other pac
+kage
$func_ref->($arg1, $arg2);
I'm sure there is a similar method like can() in Python too.
> What is the name of the idiom
When talking to non-Perlers I'd use the general term "introspection"
Update:
->can is also strict and more stable, since you can easily catch missing subs.
It won't work with AUTOLOAD though | [reply] [d/l] [select] |
|
No, you shouldn't. can performs a method lookup, not a sub lookup.
As for not working with AUTOLOAD, that would indicate a bug in the class using AUTOLOAD. It should override can to provide a meaningful result.
| [reply] [d/l] [select] |
|
> No, you shouldn't. can performs a method lookup, not a sub lookup.
->can does a sub lookup if @ISA is empty, and the content of @ISA is introspectable too.
And using a package for a module and a class is a pretty dubious concept.
| [reply] [d/l] [select] |
|
|
|
Re: Function name in a variable, can't recall the concept
by karlgoethebier (Abbot) on Apr 15, 2019 at 15:08 UTC
|
"I made the 'mistake'..."
It looks you did your pythonistic inquisitor a favor - with the result of yet another jesuitic debate here on PM 😎
"I'm a simple man" B.B. King (1925-2015)
May i ask what the hell is wrong with your dispatch table solution?
Best regards, Karl
«The Crux of the Biscuit is the Apostrophe»
perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help
| [reply] [d/l] |