2

I can't inherit the Struct. I must implement class which act like Struct. Is there a way improve my code for use "ClassName" and functional like Struct ? And write 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 Answers 2

5

Here is a version of your code which works:

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. You don't need to const_set inside the method - Dave = is enough
  2. I'm creating here an attr_accessor for each of the attributes, so you are getting a getter and a setter for each
  3. In the initialize method I'm sending each value to its corresponding setter, to set all values. If there are less values than anticipated, the last attributes will not be set, if there are more - an exception will be thrown (undefined method '=')
Sign up to request clarification or add additional context in comments.

3 Comments

WoW ! Thank you so much. Good luck for you!
Sorry If I bother you. Why I can't write k["name"] ?
A small thing: self.send can be written send.
3

Have you looked at the Struct class in Ruby?

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

Also, you shouldn't ever overwrite self.new, define initialize instead

2 Comments

Sorry , but for my task I can't inherit the Struct. I must implement class which act like Struct.
Isn't "shouldn't ever" a bit extreme? Suppose, for example, you wanted to compile a list of class instances in a class instance variable? I would view that as a job for the class, so would put it in new, rather than have instances invoke self.class.instance_variable_get... and ...set in initialize.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.