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

use*_*854 2 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
Run Code Online (Sandbox Code Playgroud)

Uri*_*ssi 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"
Run Code Online (Sandbox Code Playgroud)
  1. 你不需要const_set在方法内 - Dave =足够了
  2. 我在这里attr_accessor为每个属性创建一个,所以你得到了每个属性的getter和setter
  3. initialize方法中,我将每个值发送到其相应的setter,以设置所有值.如果值少于预期,则不会设置最后的属性,如果有更多 - 将抛出异常(undefined method '=')