2012-10-02 58 views
0

真的不知道如何標題這個問題。可以使用&符號在Ruby中打印散列嗎?

考慮一個任意哈希(ENV是方便):

ENV.each { |key, val| puts key + ': ' + val } 
LC_MESSAGES: en_US.utf-8 
LC_COLLATE: en_US.utf-8 
PWD: /Users/baller/ive_fallen_and_i_cant_get_up 
LC_MONETARY: en_US.utf-8 

是否有可能使用&:速記做到這一點?

foo.each(&:bar) 

回答

1

你可以避開兩個塊變量,並有一個代替這樣做:

each{|kv| puts kv.join(": ")} 
1

默認情況下,no。

做你想做什麼,你需要一個方法添加到Array類,打印出你想要的方式,是這樣的:

class Array 
    def bar 
    puts "#{self[0]}: #{self[1]}" 
    end 
end 

與,ENV.each(&:bar)會做你的期望。

這就是說,我不會推薦這個。添加到基類是隻有當效用遠遠超過未來衝突的可能性時才應該做的事情,並且這種方法對於具有至少2個元素的數組非常專業化。

不相關,但通過+連接字符串比使用插值要慢。它會不必要地創建額外的對象。

1

在您的示例中,使用&:bar代替塊將導致在給定對象上調用#to_proc,在這種情況下,符號:bar。 Ruby中的Symbol實現#to_proc基本上將foo.each(&:bar)擴展爲foo.each { |i| i.bar }。由於散列有兩個參數,因此本例中的i是關鍵字args的數組。這就是爲什麼你必須擴展Array(如@ x1a4所描述的那樣),以便按照預期的方式讓你的散列對待&:bar。

作爲替代方案,你可以創建自己的類來響應#to_proc或簡單地實現你的塊作爲一個Proc:

class Bar 
    def to_proc 
    Proc.new { |key, val| puts key + ': ' + val } 
    end 
end 

bar = Bar.new 

# or 

bar = Proc.new { |key, val| puts key + ': ' + val } 

帶有手柄吧,你可以通過&條代替塊到像ENV這樣的哈希。因此,考慮哈希,FOO:

foo.each(&bar) 

一個偉大的職位在這個問題上更多閱讀:http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html

1

在一般情況下,這是可能的,如果集合中的元素,以該方法作出迴應。例如:

class Foo 
    attr_reader :bar 

    def initialize(bar) 
    @bar = bar 
    end 
end 

foos = [Foo.new("one"), Foo.new("two"), Foo.new("three")] 

p foos.map(&:bar) #=> ["one", "two", "three"] 

此操作,因爲&symbol是語法糖symbol.to_proc,這反過來又一些工作魔術以返回發送該消息到它接收作爲參數的對象的塊。

雖然這不會對你的工作,例如(因爲在ENV的對象不以:bar響應),你可以通過一個已經使用&存儲在一個變量塊:

block = lambda { |key, value| puts "#{key}: #{value}" } 
ENV.each(&block) 
相關問題