我想重构一个现有的代码来简化。最初我在Java中调用模块方法,如静态实用程序方法。为什么我不能从另一个模块调用实例方法来初始化Ruby中的lambda?
这是新代码:
module Module1
def mod1() 1; end
end
module Module2
include Module1
def mod2
puts mod1()
puts 2
end
Constant = lambda { mod1() } # This line fails
end
class Sample
include Module2
def go
mod2
Constant.call # <module:Module2>': undefined method `mod1' for Module2:Module (NoMethodError)
end
end
Sample.new.go
我可以做,如果只是在Module1
代码复制到Module2
它的工作。有更好的解决方案吗?
编辑:此外,我应该能够从直接包含它的类中调用Module1
中的方法。例如:
class Sample2
include Module1
def go
puts mod1()
end
end
Sample2.new.go
实际模块1:
module HtmlUtils
def wrap(tag = :span, class_names, text)
%(<#{ tag } class="#{ class_names }">#{ text }</#{ tag }>)
end
end
实际模块2的问题是在从最后一个代码的第三复制代码。它可以用HtmlUtils#wrap方法替换。
module Markdown
include HtmlUtils
BOLD = {
regexp: /(_{2}|\*{2})(.*?)\1/,
lambda: ->(token, regexp) { "<b>#{ token[regexp, 2] }</b>" }
}
NUMBER = {
regexp: /(?<=\s|\()[+-]?(?:[1-9]\d*|0)(?:\.\d+)?(?!-|\.|\d|,\d)/,
lambda: ->(token, regexp) { %(<span class="num">#{ token }</span>) } # Redundant Code
}
end
Client1包含Markdown,实际上是HtmlUtils。
@parser.regexter('bold', BOLD[:regexp], BOLD[:lambda]);
@parser.regexter('numbers', NUMBER[:regexp], NUMBER[:lambda])
puts @parser.parse('some **string** 1') # => some <b>string</b> <span class="num">1</span>
客户端2包括HtmlUtils
@parser.regexter('quote', /(?<=)((["']).*?\2)/, ->(token, regexp) { wrap(:quote, token));
puts @parser.parse('s="Hello"') # => s=<span class="quote">"Hello"</span>
'Sample :: Constant'不知道通过'Sample.new'创建的实例。假设你有两个实例,'s1 = Sample.new'和's2 = Sample.new'。哪个'mod1'应该通过'Sample :: Constant.call'调用? – Stefan
在我的要求中,我不需要'mod1'的特定实例。它应该为每个实例返回相同的值,尽管它在实际中具有参数来进行区分。原谅我的无知,但你是否建议我应该留在使用模块方法? –
我不确定。为什么你想首先将一个proc/lamda分配给一个常量? 'Sample :: Constant.call'对我来说看起来很奇怪。 – Stefan