尝试通过Ruby创建我自己的Struct

时间:2014-06-01 13:09:26

标签: ruby struct metaprogramming

我无法继承Struct。我必须实现类似Struct的类。 有没有办法改进我的代码使用“ClassName”和功能像Struct?写k = Dave.new(“Rachel”,“Greene”)???

class MyStruct
  def self.new(*attributes)
    puts "ppp"
    dynamic_name = "ClassName"
    Kernel.const_set(dynamic_name,Class.new()  do
      attributes.each do |action|
        self.send(:define_method, action) {
          puts "call #{action}" 
        }
      end  
    end
    )
  end
end

# class ClassName
  # def new *args 
    # puts "iii"
  # end
# end



Dave = MyStruct.new(:name, :surname)

k=Dave.new()     # k=Dave.new("Rachel" , "Greene")
k.surname
k.name

2 个答案:

答案 0 :(得分:5)

以下是适用的代码版本:

class MyStruct
  def self.new(*attributes)
    Class.new do
      self.send(:attr_accessor, *attributes)
      self.send(:define_method, :initialize) do |*values|
        values.each_with_index { |val, i| self.send("#{attributes[i]}=", val) }
      end  
    end
  end
end

Dave = MyStruct.new(:name, :surname)
k = Dave.new('Rachel', 'Green')
# => #<Dave:0x00000001af2b10 @name="Rachel", @surname="Green"> 
k.name
# => "Rachel"
k.surname
# => "Green"
  1. 您不需要在方法中const_set - Dave =就够了
  2. 我在这里为每个属性创建一个attr_accessor,因此每个
  3. 都会获得一个getter和setter
  4. initialize方法中,我将每个值发送到相应的setter,以设置所有值。如果值少于预期,则不会设置最后的属性,如果还有更多 - 将抛出异常(undefined method '='

答案 1 :(得分:3)

你看过Ruby中的Struct类吗?

http://www.ruby-doc.org/core-2.1.2/Struct.html

class MyStruct < Struct.new(:first_name, :last_name)

end

MyClassObj = MyStruct.new("Gavin", "Morrice")

此外,您不应该覆盖self.new,而是定义初始化