perl是一種非常靈活的指令碼語言。 也存在對反射的需求情境。 反射就是將字串轉換為對應的語言對象。
(不考慮eval這樣的終極必殺技) 1.反射為普通變數 這個是不支援的,就是說,你沒辦法實現
my $a="b";my $b="123";print \$a; # 企圖得到"123"是不可能的
變通的辦法是使用hash
my $b='123';my $c{'b'}=$b;my $a='b';print $c{$a}; #可以從$a得到'123'
2.反射為函數 perl的函數存在一些黑魔法。不過還是建議,盡量通過hash來訪問
#反射函數#根據字串變數,動態執行函數(根據$fname調用到hello)use strict;my $fname='hello';sub hello($){my ($n)=@_;print "hello $n\n";}#hello->(); #strict不允許。原地引用&hello(1); #正式的函數調用hello(2); #這麼寫也允許#正規的函數引用my $fname3=\&hello; #\&代表取函數引用&$fname3(3); #&執行$fname3->(4);#正規的做法。先註冊函數到hash。my %fh;$fh{"hello"}=\&hello;$fh{"$fname"}(9); #再通過名字變數調用#&{$fh{"$fname"}}(9); #也可以#反射的黑魔法"hello"->(5); #允許。但是沒什麼用#$fname->(); #strict不允許#&{$fname}();#strict不允許#\&{$fname}->(); #strict不允許&{\&{$fname}}(6); #這麼寫可以,不過有點難懂my $fname2= \&{"hello"}; #magictrick&$fname2(7);my $fname1 = \&{$fname};&$fname1(8); #前面的&是必需的
3.反射為模組 可以通過 require $mname; 就可以了 不過use不行。 perl沒有python那樣的getattr函數 不過可以和函數反射一樣處理
#!/usr/bin/perluse FindBin qw($Bin);use lib "$Bin";my $mname="Foo1.pm"; #通過變數載入模組#require Foo1;require $mname;Foo1::bar( "a" );Foo1::blat( "b" );my $fname="Foo1::blat";my $fname1 = \&{$fname}; #通過變數執行函數&$fname1("b");