2016-01-21 55 views
3

匿名子我是新來的Ruby和試圖複製這個perl,它調用的匿名子,在紅寶石:Perl的像紅寶石

#!/usr/bin/perl 

use strict; 
use warnings; 
use feature 'say'; 

# Make a reference to a subroutine 
my $codes = { 
    one => sub { 
     say "This is code block one"; 
     say "And this is code block one's line two" 
    }, 
}; 

for my $next_code (keys %{ $codes }) { 
    # Execute anonymous subroutine 
    &{ $codes->{ $next_code } }; 
} 

我嘗試這樣做:

#!/usr/bin/ruby -w 

codes = { 
    one: puts "This is code block one" 
     puts "And this is code block one's line two", 
} 
codes.each do |next_code| 
    next_code 
end 

但是,我得到語法錯誤。這是可能的,還是有另一種首選的紅寶石方式?

更新:是的,這就像一個調度表。我將代碼存儲在一個散列中,稍後再運行該代碼。

+1

看起來你可能試圖實現一個調度表。如果是這樣,在你的問題中提到避免XY問題是很好的。在Ruby中可能有更好的方法,它採用與Perl完全不同的方法。 – ThisSuitIsBlackNot

+1

你能用普通詞(不是perl代碼)解釋你想做什麼? –

+4

'最好寫成'$ code - > {$ next_code} - >()' – Borodin

回答

7

紅寶石有Proc s作爲匿名頭等子程序對象。 Proc s可以通過將一個塊傳遞給Proc::newKernel#procKernel#lambda或者使用「stabby lambda」lambda文字語法來創建。

#!/usr/bin/env ruby 

# Make a reference to a subroutine 
codes = { 
    one: -> { 
    puts "This is code block one" 
    puts "And this is code block one's line two" 
    } 
} 

codes.each do |name, code| 
    # Execute anonymous subroutine 
    code.() 
end 

在紅寶石匿名碼塊的最廣泛使用的形式是被稱爲構建體,這實際上不是一個對象,而只是一個語法構造。 Ruby中的每個方法都只有一個可選的塊參數,它可以通過大括號或在普通方法參數後面使用關鍵字對來傳遞。您可以在上面的代碼中看到正在執行的塊,並將其傳遞給迭代方法Hash#each

如果您有興趣,這裏是我的一個小型玩具項目,演示了使用各種語言的一流的閉包,包括Perl5和Perl6,Ruby,PHP,Python,ECMAScript,Smalltalk,Clojure, Scheme和其他許多方面:http://joergwmittag.github.io/lambdaconscarcdr/

+1

有趣的事情有一點特別有趣的是它們可以被調用(至少?)五方法。假設'f = - > s {放置「說#{s}!」 }'。然後'f.call('hey')','f ['hey']','f。('hey')','f.yield('hey')'和'f ===「嘿」 '全部打印'「說嘿!」'。 –

+1

雖然「正常」的方式是使用'call'或者它的語法糖'。()'。 '[]'是'call'的過時別名,用於通過使用括號作爲假圓括號來調用'Proc'更像方法調用。從Ruby 1.9開始,我們使用'。()'符號,這更符合IMO的需要。 'yield'我不知道,我想這是爲了API與Fibre的兼容性? '==='在'case'表達式和'Enumerable#grep'中使用'Proc'很有用,但可能不應該直接調用。注意:除了'('''''''''''''''''''''''是'call'的語法糖之外,它們都是'call'的別名。 –