声明实例变量迭代哈希!

发布于 2024-08-08 06:45:35 字数 481 浏览 4 评论 0原文

我想做以下事情:

我想声明迭代字典的类的实例变量。

假设我有这个哈希

hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}

,并且我希望将每个键作为类的实例变量。我想知道我是否可以声明迭代该哈希的变量。像这样的东西:

class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      @k = v
    end
  end
end

我知道这不起作用!我只是放这段代码来看看你是否能更清楚地理解我想要的东西。

谢谢!

i want to do the following:

I want to declare the instance variables of a class iterating over a dictionary.

Let's assume that i have this hash

hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}

and i want to have each key as instance variable of a class. I want to know if i could declare the variables iterating over that hash. Something like this:

class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      @k = v
    end
  end
end

I know this doesn't work! I only put this piece of code to see if you could understand what i want more clearly.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘亓 2024-08-15 06:45:36

http://facets.rubyforge.org/apidoc/api/more/类/OpenStrutable.html

OpensStrutable是一个mixin模块
它可以提供 OpenStruct 行为
任何类或对象。开放结构
允许扩展数据对象
任意属性。

http://facets.rubyforge.org/apidoc/api/more/classes/OpenStructable.html

OpensStructable is a mixin module
which can provide OpenStruct behavior
to any class or object. OpenStructable
allows extention of data objects with
arbitrary attributes.

平生欢 2024-08-15 06:45:35
class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      instance_variable_set("@#{k}",v)
      # if you want accessors:
      eigenclass = class<<self; self; end
      eigenclass.class_eval do
        attr_accessor k
      end
    end
  end
end

特征类是一个只属于单个对象的特殊类,因此定义的方法将具有该对象的实例方法,但不属于该对象普通类的其他实例。

class MyClass
  def initialize()
    hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    hash.each do |k,v|
      instance_variable_set("@#{k}",v)
      # if you want accessors:
      eigenclass = class<<self; self; end
      eigenclass.class_eval do
        attr_accessor k
      end
    end
  end
end

The eigenclass is a special class belonging just to a single object, so methods defined there will be instance methods of that object but not belong to other instances of the object's normal class.

花海 2024-08-15 06:45:35
class MyClass
  def initialize
    # define a hash and then
    hash.each do |k,v|
      # attr_accessor k # optional
      instance_variable_set(:"@#{k}", v)
    end
  end
end
class MyClass
  def initialize
    # define a hash and then
    hash.each do |k,v|
      # attr_accessor k # optional
      instance_variable_set(:"@#{k}", v)
    end
  end
end
自由如风 2024-08-15 06:45:35

查克的回答比我前两次的尝试要好。 eigenclass 并不像我想象的那样 self.class;我花了比我写的更好的测试来认识到这一点。

使用我的旧代码,我按以下方式进行测试,发现该类确实被操纵,而不是实例:

a = MyClass.new :my_attr => 3
b = MyClass.new :my_other_attr => 4

puts "Common methods between a & b:"
c = (a.public_methods | b.public_methods).select { |v| a.respond_to?(v) && b.respond_to?(v) && !Object.respond_to?(v) }
c.each { |v| puts "    #{v}" }

输出是:

Common methods between a & b:
    my_other_attr=
    my_attr
    my_attr=
    my_other_attr

这显然反驳了我的假设。抱歉,查克,你一直都是对的。

旧答案:

attr_accessor 仅在类定义中评估时才起作用,而不是在实例的初始化中评估。因此,直接执行您想要的操作的唯一方法是将 instance_eval 与字符串一起使用:

class MyClass
  def initialize(params)
    #hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    params.each do |k,v|
      instance_variable_set("@#{k}", v)
      instance_eval %{
        def #{k}
          instance_variable_get("@#{k}")
        end
        def #{k}= (new_val)
          instance_variable_set("@#{k}", new_val)
        end
      }
    end
  end
end

要测试此尝试:

c = MyClass.new :my_var => 1
puts c.my_var

Chuck's answer is better than my last two attempts. The eigenclass is not self.class like I had thought; it took a better test than I had written to realize this.

Using my old code, I tested in the following manner and found that the class was indeed manipulated and not the instance:

a = MyClass.new :my_attr => 3
b = MyClass.new :my_other_attr => 4

puts "Common methods between a & b:"
c = (a.public_methods | b.public_methods).select { |v| a.respond_to?(v) && b.respond_to?(v) && !Object.respond_to?(v) }
c.each { |v| puts "    #{v}" }

The output was:

Common methods between a & b:
    my_other_attr=
    my_attr
    my_attr=
    my_other_attr

This clearly disproves my presupposition. My apologies Chuck, you were right all along.

Older answer:

attr_accessor only works when evaluated in a class definition, not the initialization of an instance. Therefore, the only method to directly do what you want is to use instance_eval with a string:

class MyClass
  def initialize(params)
    #hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
    params.each do |k,v|
      instance_variable_set("@#{k}", v)
      instance_eval %{
        def #{k}
          instance_variable_get("@#{k}")
        end
        def #{k}= (new_val)
          instance_variable_set("@#{k}", new_val)
        end
      }
    end
  end
end

To test this try:

c = MyClass.new :my_var => 1
puts c.my_var
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文