如何在Ruby中设置哈希实例的值?

don*_*ior 2 ruby metaprogramming

我有两个A和B类,它们都有一些选项,通常我会用一个Hash来存储选项,比如@options[:name]='xxxx'; 现在我想用元编程重构它,

class A
    set_option :name, "james"
    set_option :address, "some street"

    def hello
        puts @options[:name]
        puts @options[:address]
    end
end


class B
    set_option :age, 18

    def greeting
        put @options[:age]
    end
end 
Run Code Online (Sandbox Code Playgroud)

这里我想用来set_option将键和值对设置为一个哈希实例@options,我该怎么办呢?

此外,我想将解决方案包装到一个单独的模块中.

更新:

首先,感谢你所有的答案对我都有价值,让我更清楚,现在我意识到我想要的东西不是那么正确,那么如果我提出这样的问题呢?

  • 怎么用一种方法option来代替@options?
  • A类和B类都可以为同一个键设置不同的选项,所以可能有些答案' @@options不起作用?我希望不同的类可以有不同的哈希实例.

```像这样:

class A
    set_option :name, "james"
    set_option :provider, 'twitter'

    def hello
        puts option[:name]
    end
end


class B
    set_option :name, "not james"

    def greeting
        put option[:name]
    end
end 
Run Code Online (Sandbox Code Playgroud)

经过深思熟虑后,我认为我真正想要的是不同类的不同选项哈希实例,而不是类的实例.

这是我想要的,它可以工作.

module HasOptions
  def self.included(cls)
    cls.class_eval do
      def self.set_option(key, value)
        options[key] = value
      end

      def self.options
        @options ||= {}
      end

      def options
        self.class.options
      end
    end
  end
end


class Baz
  include HasOptions
  set_option :name, "bad"

  def greeting
        puts options[:name]
  end
end

class Foo
  include HasOptions
  set_option :name, "foo"

  def greeting
        puts options[:name]
  end
end
Run Code Online (Sandbox Code Playgroud)

感谢你的帮助.

Ale*_*x D 5

正如您尝试的那样使用实例变量将无法正常工作.但是,您可以使用以下方法:

module HasOptions
  def self.included(cls)
    cls.class_eval do
      def self.set_option(key, value)
        (@@options ||= {})[key] = value
      end
    end
  end

  def options
    @options ||= @@options.dup
  end
end
Run Code Online (Sandbox Code Playgroud)

此实现允许您设置每个实例选项,而不会覆盖所有实例的公共选项.