Ruby:方法作为数组元素 – 它们如何工作?

这可能不是你应该在家里尝试的东西,但由于某种原因我试图在Ruby中创建一个方法数组。

我开始定义两种方法。

irb(main):001:0> def test1 irb(main):002:1> puts "test!" irb(main):003:1> end => nil irb(main):004:0> def test2 irb(main):005:1> puts "test2!" irb(main):006:1> end => nil 

当你试图把它放到一个实际的数组中时会发生奇怪的事情。 它似乎运行两种方法。

 irb(main):007:0> array = [test1, test2] test! test2! => [nil, nil] 

然后,arrays是空的。

 irb(main):008:0> puts array => nil 

有人可以向我解释为什么它运行这些方法吗? 除此之外,整个运动是否真的需要一个驱魔人?

你在数组中存储的是调用方法的结果,而不是方法本身。

 def test1 puts "foo!" end def test2 puts "bar!" end 

您可以存储对实际方法的引用,如下所示:

 > arr = [method(:test1), method(:test2)] # => [#, #] 

稍后,您可以像这样调用引用的方法:

 > arr.each {|m| m.call } foo! bar! 

@alestanis很好地解释了原因。 如果你试图存储方法,那么你可以做Lars Haugseth所说的或者你可以做以下事情:

 test1 = Proc.new { puts "test!" } test2 = Proc.new { puts "test2!" } a = [test1, test2] 

这可能会使您的代码更具可读性。

这是一个irb run。

 1.9.3p194 :009 > test1 = Proc.new { puts "test!" } => # 1.9.3p194 :010 > test2 = Proc.new { puts "test2!" } => # 1.9.3p194 :011 > a = [test1, test2] => [#, #] 

您的数组永远不会包含除两个nil值之外的任何值。 我在评估时通过放置字符串来欺骗你。 但每个函数的返回值仍为零。

您的代码运行这两种方法,因为当您说“test1”和“test2”时,您实际上正在调用方法 – 括号对于ruby方法调用是可选的。

由于两个方法都只包含一个返回nil的“puts”,因此生成的数组只是一个包含两个nils的数组。

如果你有一个square方法并且想要创建一个方形值为2和4的数组,那么你会写

 array = [square(2), square(4)] 

在这里你做的完全相同,除了你的测试方法没有返回任何东西,这就是为什么你的最终array似乎是空的(实际上,它包含[nil, nil] )。

这是我的两便士价值。 基于已发布的解决方案,这是一个工作示例的示例。 对于某些人来说可能有用的是它包含方法参数和self的使用(在实例化时引用PromotionalRules类的实例)和符号数组,这很简洁 – 我从Ruby文档得到了它在#send方法这里 。 希望这有助于某人!

 class PromotionalRules PROMOTIONS = [:lavender_heart_promotion, :ten_percent_discount] def apply_promotions total, basket @total = total if PROMOTIONS.count > 0 PROMOTIONS.each { |promotion| @total = self.send promotion, @total, basket } end @total.round(2) end def lavender_heart_promotion total, basket if two_or_more_lavender_hearts? basket basket.map { |item| total -= 0.75 if item == 001 } end total end def two_or_more_lavender_hearts? basket n = 0 basket.each do |item| n += 1 if item == 001 end n >= 2 end def ten_percent_discount total, *arg if total > 60.00 total = total - total/10 end total end end 

感谢大家的帮助。 我喜欢编码的开源本质 – 当人们迭代彼此的解决方案时,线程会越来越好!