所以,这就是我到目前为止所做的:
# @return [Array<Hash>] of variables ([Placeholders, actual variables])
def variables
# @return [Hash] of all variables.
# If actual variables are named teh same as the placeholders, the placeholders will be over written.
# This implementation of merging hashes of an array will work even if we add more elements to the
# variables array.
self.class.send(:define_method, "variables.flatten") do
return self.variables.inject{|placeholders, vars| placeholders.merge(vars || {})}
end
return [placeholder_variables, self.variable_data]
end
我希望能够做到:
my_object.variables # => return the Array<Hash>
但也能够做到
my_object.variables.flatten # => return a single merged hash
我刚做的时候的问题
def variables.flatten
是当我运行控制台时,我收到一条错误消息,指出variables
未定义(或者我在.flatten
之前放置的任何内容)
我是否可以仅在.flatten
属性上定义自定义variables
方法? (正常<Array>.flatten
在这里不起作用,因为我需要合并哈希。)
答案 0 :(得分:1)
直接回答:在自己的模块中定义方法,然后将其包含在您返回的数组中:
module SpecialFlatten
def flatten
first.update last
end
end
......以后......
def variables
vals = [placeholder_variables, self.variable_data]
return vals.extend(SpecialFlatten)
end
但在这种情况下,更好的选择可能是这样做:
def variables(*flags)
if flags.include? :flatten
placeholder_variables.update self.variable_data
else
[placeholder_variables, self.variable_data]
end
end
答案 1 :(得分:0)
我认为不可能定义“variables.flatten”方法。为了证明我们通过这个例子来检查:
require 'ruby_parser'
RubyParser.new.parse(<<-EOF)
my_object.variables.flatten
EOF
#=> s(:call,
s(:call, s(:call, nil, :my_object, s(:arglist)), :variables, s(:arglist)),
:flatten,
s(:arglist))
正如您所看到的,variables
和flatten
是不同的令牌,并且它们无法合并为一个令牌,这是一个解析问题。
但有一点可能是你错过了 - 这就是可连接性。方法variables
返回变量数组,如果它们响应flatten方法,结果将是平坦的。如果他们没有响应该方法,您应该为这些对象实现flatten
方法。
答案 2 :(得分:0)
您可以在返回值上定义单例方法。
def variables
result = [placeholder_variables, self.variable_data]
# redefine method flatten on the result array
def result.flatten
# did not understand what you are trying to do here
# self is the array here
inject{|placeholders, vars| placeholders.merge(vars || {})}
end
return result # return the array with added method
end
然而,这几乎总是一个坏主意。
答案 3 :(得分:0)
Array#flatten
方法是Ruby核心的一部分,因此我建议不要更改它,特别是如果您正在与其他开发人员合作。您似乎正在尝试使用现有界面。我会寻找替代方法,但您可以在variables
方法的返回值上覆盖flatten方法。
def variables
[placeholder_variables, self.class.variable_data].tap do |vars|
vars.instance_eval do
def flatten
inject{|result, vars_hash| result.merge!(vars_hash)}
end
end
end
end