Ruby:模块,Mixin和块令人困惑吗? [英] Ruby: Module, Mixins and Blocks confusing?
问题描述
以下是我尝试从Ruby Programming
书中运行的代码
http://www.ruby-doc.org/docs/ProgrammingRuby/html /tut_modules.html
为什么product
方法没有提供正确的输出?
我用irb test.rb
来运行它.我正在运行Ruby 1.9.3p194
.
module Inject
def inject(n)
each do |value|
n = yield(n, value)
end
n
end
def sum(initial = 0)
inject(initial) { |n, value| n + value }
end
def product(initial = 1)
inject(initial) { |n, value| n * value }
end
end
class Array
include Inject
end
[1, 2, 3, 4, 5].sum ## 15
[1, 2, 3, 4, 5].product ## [[1], [2], [3], [4], [5]]
顺便说一句:在Ruby 2.0中,有两个功能可以帮助您解决两个问题.
Module#prepend
在继承链中添加,以便将混入模块/类中的mixin override 方法中定义的方法混入其中. /p>
精炼允许按词法作用域进行猴子修补.
它们在起作用(您可以通过RVM或ruby-build轻松获得最新版本的YARV 2.0):
module Sum
def sum(initial=0)
inject(initial, :+)
end
end
module ArrayWithSum
refine Array do
prepend Sum
end
end
class Foo
using ArrayWithSum
p [1, 2, 3].sum
# 6
end
p [1, 2, 3].sum
# NoMethodError: undefined method `sum' for [1, 2, 3]:Array
using ArrayWithSum
p [1, 2, 3].sum
# 6
Following is the code I tried to run from the Ruby Programming
Book
http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html
Why doesn't the product
method give the right output?
I ran it with irb test.rb
. And I am running Ruby 1.9.3p194
.
module Inject
def inject(n)
each do |value|
n = yield(n, value)
end
n
end
def sum(initial = 0)
inject(initial) { |n, value| n + value }
end
def product(initial = 1)
inject(initial) { |n, value| n * value }
end
end
class Array
include Inject
end
[1, 2, 3, 4, 5].sum ## 15
[1, 2, 3, 4, 5].product ## [[1], [2], [3], [4], [5]]
By the way: in Ruby 2.0, there are two features which help you with both your problems.
Module#prepend
prepends a mixin to the inheritance chain, so that methods defined in the mixin override methods defined in the module/class it is being mixed into.
Refinements allow lexically scoped monkeypatching.
Here they are in action (you can get a current build of YARV 2.0 via RVM or ruby-build easily):
module Sum
def sum(initial=0)
inject(initial, :+)
end
end
module ArrayWithSum
refine Array do
prepend Sum
end
end
class Foo
using ArrayWithSum
p [1, 2, 3].sum
# 6
end
p [1, 2, 3].sum
# NoMethodError: undefined method `sum' for [1, 2, 3]:Array
using ArrayWithSum
p [1, 2, 3].sum
# 6
这篇关于Ruby:模块,Mixin和块令人困惑吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!