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