如何设置哈希实例';在Ruby中这样的值是多少?

如何设置哈希实例';在Ruby中这样的值是多少?,ruby,metaprogramming,Ruby,Metaprogramming,我有两个类A和B,它们都有一些选项,通常我会使用一个散列来存储选项,比如@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

我有两个类A和B,它们都有一些选项,通常我会使用一个散列来存储选项,比如
@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 
在这里,我想使用
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 
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
经过深思熟虑,我认为我真正想要的是不同类的不同选项哈希实例,而不是类的实例

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

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

感谢您的帮助。

使用实例变量(您正试图这么做)是行不通的。但是,您可以使用如下方法:

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 
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

此实现允许您设置每个实例选项,而无需覆盖所有实例的公共选项。

如果需要init实例选项,则应使用实例方法来实现

module OptionSetter
  def set_option(key, value)
    @options[key] = value
  end
end

class Base
  def initialize(options = {})
    @options = {}
    options.each do |key, value|
      set_option key, value
    end
  end
end

class A < Base
  include OptionSetter

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

class B < Base
  include OptionSetter

  def greeting
    puts @options[:age]
  end
end

A.new(name: "james", address: "some street").hello
B.new(age: 18).greeting

看起来你把事情搞砸了。让我试着列出你想要解决的问题:

  • 将选项存储在类变量
    散列
    的实例中(我得到的正确吗?-所有类实例都有一个散列)
    
  • 使用漂亮的符号来设置选项
上面的任何内容实际上都不需要元编程。要满足第一个条件,您只需找到所有类的第一个公共祖先,并使用
@@options
var和
set\u option
方法对其进行修补。如果您没有决定为所有类提供自己的超类,那么让我们修补祖先(例如,
Kernel
module):

现在,任何类都可以包含
set_option
“指令”以将选项放入共享选项哈希中(考虑使用实例变量
@options
而不是
@@options
使选项特定于实例,或者使用Alex D的解决方案。)


如果您想为选项设置(使用默认值、原地跳棋、帆布包和奢侈品)提供花哨的语法,您可以在这里使用。中的第一个示例演示了如何使用DSL实现纯
set_选项。进一步的调整仅限于您的想象力。

谢谢@mudasobwa,对于您列出的问题项,第一个不是我想要的,我想要不同类的不同哈希实例。@donnior然后简单地去掉double
@
,在注释中建议的任何解决方案中使用
@options
。-)