在Spree框架中,Product
模型定义了一个名为build_variants_from_option_values_hash
的私有方法。
此方法通常由after_create
回调在内部调用,并在类中声明为private
。我想在正常情况下使用这种方法"创建"生命周期并直接调用它,但是因为它是私有声明的,不幸的是它在类之外是不可见的。
问题:有没有办法在不重新定义方法的情况下更改/修改方法的可见性?
使用class_eval
,我可以在private
区域之外的产品装饰器中重新定义该方法,这确实可以解决问题。但是,我觉得完全复制整个方法只是为了改变它的可见性是一种不必要的猴子修补"型方法。有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
虽然@МалъСкрылевъ的方法更明智,IMO,您也可以创建该方法的公共别名:
Product.class_eval do
alias_method :public_build_variants, :build_variants_from_option_values_hash
public :public_build_variants
end
现在可以用作
p = Product.new
p.public_build_variants
答案 1 :(得分:1)
重新定义ruby
中方法的可见性的方法并不好。但是,您可以通过将相同的方法重新定义到公共空间来完成此操作,如下所示:
class CC
private
def private_method
end
end
CC.new.private_method # => NoMethodError: private method `private_method' called for #<CC:0x8166144>
method = CC.instance_method(:private_method)
CC.send(:remove_method, :private_method)
CC.send(:define_method, :private_method, method)
CC.new.private_method # => nil
但调用私有方法的正确方法是使用#send
公共方法,如下所示:
object.send :private_method, *args