0

I have a class with (as example) 3 attributes ,I want to convert the class's attribute to an array ,so I can store them into my csv file.

class Human
   attr_accessor :name,:Lname,:id
   ....
end

when I create :

 human1=Human.new("nice","human",1)

I need a function that return ["nice","human",1].

Is there a predefined one that I didn't find or I have to redefine to_a so it does the job.

note: the class has more than 3 attribute

  • is there a function to go through the object attribute or not.
1
  • The closest Ruby seems to offer is the method instance_variables, which returns an Array of symbols, representing the currently defined instance variables. However, using attr_accessor without actually setting the variables somewhere, does not create variables (this would typically be done in your initialize method). You can of course use the method instance_methods to get a list of symbols of all your methods, and then find in it those which look like attribute accessors. Since your question is a bit unclear, I can't say whether or not this will help you. Commented Apr 8, 2022 at 6:01

2 Answers 2

2

I need a function that return ["nice","human",1]

Creating such method is trivial. If it is specifically for CSV, I would name it accordingly, e.g.:

class Human
   attr_accessor :name, :lname, :id

   # ...

   def to_csv
     [name, lname, id]
   end
end

To generate a CSV:

require 'csv'

human1 = Human.new("nice", "human", 1)

csv_string = CSV.generate do |csv|
  csv << ['name', 'lname', 'id']
  csv << human1.to_csv
end

puts csv_string
# name,lname,id
# nice,human,1

Note that I've renamed Lname to lname in the above example. Uppercase is reserved for constants.

Sign up to request clarification or add additional context in comments.

Comments

1

is there a function to go through the object attribute or not?

No, there is no built in way to actually do what you want and you might be falling for a common beginner trap.

attr_accessor does not "define attributes" since Ruby doesn't actually have properties/attributes/members like other langauges do. It defines a setter and getter method for an instance variable. Ruby doesn't keep track of which properties an object is presumed to have - only the actual instance variables which have been set.

But Ruby does provide the basic building blocks to make any kind of attributes system you want. This is very simplefied (and quite rubbish) example:

class Human
  # this is a class instance variable
  @attributes = []
    
  # a class method that we use for "defining attributes"
  def self.attribute(name)
    attr_accessor name
    @attributes << name
  end

  attribute(:name)
  attribute(:l_name)
  attribute(:id)

  def initialize(**kwargs)
    kwargs.each {|k,v| send("#{k}=", v) }
  end

  # the attributes that are defined for this class
  def self.attributes
    @attributes
  end

  # cast a human to an array
  def to_a
    self.class.attributes.map{ |attr| send(attr) }
  end

  # cast a human to an hash
  def to_h
    self.class.attributes.each_with_object({}) do |attr, hash| 
      hash[attr] = send(attr)
    end
  end
end
jd = Human.new(
  name: 'John',
  l_name: 'Doe',
  id: 1
)

jd.to_a # ['John', Doe, 1]
jd.to_h # {:name=>"John", :l_name=>"Doe", :id=>1}   

Here we are creating a class method attribute that adds the names of the "attributes" to a class instance variable as they are declared. Thus the class "knows" what attributes it has. It then uses attr_accessor to create the setter and getter as usual.

When we are "extracting" the attributes (to_a and to_h) we use the list we have defined in the class to call each corresponding setter.

Usually this kind functionality would go into a module or a base class and not the actual classes that represent your buisness logic. For example Rails provides this kind of functionality through ActiveModel::Attributes and ActiveRecord::Attributes.

4 Comments

@Stefan's answer is probably better if you're just looking for a straight forward way of outputing an array to insert into a CSV file.
max thank you for taking time writing the informative respond .can u just tell me if I'm right so in ruby there is no way to track the variables of the class so we need to keep them in a class array so we know what are the class's attribute and than we can through all of them
Yes. Ruby doesn't have something like getDeclaredFields in Java or get_object_vars in PHP. It has a very different object model where instance variables are not declared properties - they are just local variables which are scoped to an object.
You can get the set instance variables with the instance_variables method but thats really not the same thing.

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.