如何从 Ruby 中的子类覆盖 lambda 变量?

How to override a lambda variable from a subclass in Ruby?

我正在使用 Redis gem to access redis, and I would like .hgetall to symbolize the keys of the hashes it returns. In this thread,@pletern 表示猴子修补 gem 的 _hashify 方法的方法。

然而,这是不久前的事了,当前的实现使用 lambda 来 Hashify 从 Redis 返回的列表,而不是方法。 See line 2728

我一直在尝试 'override' 使用我自己的实现来执行此 lambda,遵循与方法类似的内容:

class MyRedis < Redis

  private

  Hashify =
    lambda { |array|
      hash = Hash.new
      array.each_slice(2) do |field, value|
        hash[field.to_sym] = value
      end
      hash
    }
end

在我的 RedisService 中:

class RedisService
  class << self

    def hgetall(key)
      redis.hgetall("room:"+room_name)
    end

    private

    def redis
      @@redis ||= MyRedis.new
    end

  end
end

我玩过 class,但无法覆盖 gem 中的 Hashify lambda。

在子类中设置自己的 Hashify 没有帮助,因为 Ruby 解释器将使用 Redis 中定义的常量作为调用 Hashify.call 的方法] 也在那里定义。

不过您可以覆盖 Redis::Hashify。这将导致您的 lambda 用于所有 Redis 连接和 warning: already initialized constant Redis::Hashify

require 'redis'

Redis::Hashify = lambda do |array|
  Hash.new.tap do |hash|
    array.each_slice(2) do |field, value|
      hash[field.to_sym] = value
    end
  end
end

请注意编写会产生警告的代码被许多开发人员认为是糟糕的风格。收到 Redis#hgetall 的回复后,最好修改一下。如果您不介意使用 ActiveSupport,您可以使用它的 Hash#symbolize_keys,例如。