Ruby 将to_hash(或to_h)方法添加到Struct的优雅方式?

Ruby 将to_hash(或to_h)方法添加到Struct的优雅方式?,ruby,ruby-1.9.3,Ruby,Ruby 1.9.3,我在项目中使用Struct而不是简单的散列来为键值对集合提供语义名称。然而,一旦我构建了这个结构,我就需要输出一个散列值。我用的是Ruby 1.9.3。例如: MyMeaninfulName = Struct.new(:alpha, :beta, :gamma) do def to_hash self.members.inject({}) {|h,m| h[m] = self[m]; h} end end my_var = MyMeaningfulName.new my_var

我在项目中使用Struct而不是简单的散列来为键值对集合提供语义名称。然而,一旦我构建了这个结构,我就需要输出一个散列值。我用的是Ruby 1.9.3。例如:

MyMeaninfulName = Struct.new(:alpha, :beta, :gamma) do
  def to_hash
    self.members.inject({}) {|h,m| h[m] = self[m]; h}
  end
end

my_var = MyMeaningfulName.new
my_var.to_hash # -> { :alpha=>nil, :beta=>nil, :gamma=>nil } 
Struct不包含to_散列方法有什么原因吗?这看起来很自然,但也许有一个潜在的原因,为什么它没有包括在内

其次,是否有更优雅的方法将泛型to_散列方法构建到Struct中(通常通过monkeypatching,或通过模块或继承)

class Struct
  old_new = self.method(:new)
  def self.new(*args) 
    obj = old_new.call(*args)
    obj.class_exec do
      def to_hash
        self.members.inject({}) {|h,m| h[m] = self[m]; h}
      end
    end
    return obj
  end
end
或者这个:

class Struct
  def to_hash
    self.class.members.inject({}) {|h,m| h[m] = self[m]}
  end
end

(请注意额外的课程以获得会员)

我不知道为什么,这似乎是显而易见的。幸运的是,您可以在许多地方将其用作哈希,因为它实现了括号运算符

无论如何,这是相当优雅的:

MyMeaningfulName = Struct.new :alpha, :beta, :gamma do
  def to_hash
    Hash[members.zip values]
  end
end

my_var = MyMeaningfulName.new 1, 2, 3
my_var.to_hash # => {:alpha=>1, :beta=>2, :gamma=>3}

我知道问题是关于ruby 1.9.3的,但是从ruby 2.0.0开始,
Struct
有一个方法来完成这项工作

MyMeaningfulName = Struct.new(:alpha, :beta, :gamma)

my_var = MyMeaningfulName.new
my_var.to_h # -> { :alpha=>nil, :beta=>nil, :gamma=>nil } 

为了澄清问题的第二部分。。。因为Struct是一个类工厂,我不确定如何添加to_散列功能(在任何传统类中都很容易)。如果您想澄清,可以编辑问题--只需单击问题文本下的编辑链接。顺便提一下,好问题+1.我相信您的注入块缺少
h
作为返回值;这给我带来了一个例外。或者使用
each
并将
h
移动到外部范围。我在这个答案和Linuxios之间左右为难。他的话更罗嗦,但对我来说,更明确地说明了到底发生了什么。@GSP-同意-简短并不总是最好的我得到了
未定义的局部变量或Struct:Class`的方法old\u new
当我尝试时:
Class MyClass