【问题标题】:Override module class method覆盖模块类方法
【发布时间】:2014-05-23 10:28:22
【问题描述】:

我正在尝试覆盖第三方提供的模块中的类方法。

我的目标是检查第二个参数,如果是哈希则实例化一个新的自定义对象,否则调用原始实现:

module ThirdParty
  def self.login(email, password_or_options)
    if password_or_options.is_a?(Hash)
      SafeSession.new(email, password_or_options['sid'], password_or_options['master_key'], password_or_options['shared_keys'], password_or_options['rsa_privk']).storage
    else
      super(email, password_or_options)
    end
  end

原始方法签名:

module ThirdParty
  def self.login(email, password)
    # Library doing its own stuff
  end
end

目前这失败了

ThirdParty.login('email', { test: true })
NoMethodError: super: no superclass method `login' for ThirdParty:Module

我也在使用 ActiveSupport,以防在这个框架中有解决这个问题的方法。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    试试:

    module ThirdParty
      class << self
        def login_with_change(email, password_or_options)
          if password_or_options.is_a?(Hash)
            SafeSession.new(email, options['sid'], password_or_options['master_key'], password_or_options['shared_keys'], password_or_options['rsa_privk']).storage
          else
            login_without_change(email, password_or_options)
          end
        end
        alias_method_chain :login, :change
      end
    end
    

    【讨论】:

    • 我在alias_method_chain 线上收到了undefined method 'login' for class 'Module'。谢谢。
    • 您确定login 方法是在第三方登录中定义的,而不是在其中包含的模块之一中?
    • 此时我不确定。我试图覆盖的代码是:github.com/topac/rmega/blob/master/lib/rmega/session.rb#L7
    • 所以ThirdParty 真的是Rmega
    • 是的,我没有指定有问题的库名称,因为我认为它不相关 :) 谢谢。
    【解决方案2】:

    也许这会奏效 使用 alias_method 为 monkey_patched 模块中的原始方法起别名

     module ThirdParty
       class << self
         alias_method :login_ori, :login
       end
       def self.login(email, password_or_options)
         if password_or_options.is_a?(Hash)
           SafeSession.new(email, password_or_options['sid'], password_or_options['master_key'], password_or_options['shared_keys'], password_or_options['rsa_privk']).storage
         else
           login_ori(email, password_or_options)
         end
       end
     end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-07
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多