1

I have a class that reads a dynamic CSV file, and would like to create a struct based on the headers of the CSV.

It goes like this in pseudo-code:

class SomeClass
  def initialize(csvfile)
    @csv = CSV.open(csvfile, options.....)
    .....
    headers = @csv.headers  # => [:line, :error, :user, ........]   <==this is dynamic
    RECORD = Struct.new(headers)
    load_data
  end

  def load_data
    @records = []
    @csv.each do |r|
      @records << RECORD.new(r.fields)
    end
  end
end

The issue is that a constant can not (should not) be dynamically defined. So, what should be the proper way to address this?

4
  • possible duplicate of Dynamic constant assignment Commented Jul 17, 2014 at 13:13
  • Not a dup actually. The issue is with the proper use of struct and not with the constant. Commented Jul 18, 2014 at 2:16
  • "The issue is that a constant can not (should not) be dynamically defined. So, what should be the proper way to address this?" Commented Jul 18, 2014 at 13:16
  • Regardless of whether you are talking about a Struct, a Hash, or a String, you can't dynamically assign to a constant. The important part of this question asks how to address the fact that a constant can not be dynamically defined, which is why I see it as a duplicate. Well, that's my reasoning anyway... Commented Jul 18, 2014 at 13:21

2 Answers 2

3

You don't have to use a constant. Use an instance variable.

class SomeClass
  def initialize(csvfile)
    @csv = CSV.open(csvfile, options...)
    ...
    headers = @csv.headers
    @record = Struct.new(headers)
    load_data
  end
  def load_data
    @records = []
    @csv.each do |r|
      @records << @record.new(r.fields)
    end
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

OK, perfect, I've should have specified I knew that. The issue here is that I WANT it to be a constant, which will be initialized just once. Said that, what I would like is a constant that can be initialized dynamically upon initialization.
0

@sawa's answer is correct. I will add something more here.

Constants are used to store values which DO NOT change. If you change a constant in your program it is probably a bug. Ruby is trying to be helpful and say "Hold on! I think something strange is going on here. You said you wanted this to be a constant but now it's being changed!"

In Ruby, you are never allowed to put a constant assignment, inside a method definitions due to the reason as I just said above. If you try to do constant assignment inside a method, you will get Syntax Error. As per your need, you can use any variables, but not constant variables, inside a method.

If you do

Y = 1
#then
Y = 2
# warning: already initialized constant Y
# warning: previous definition of Y was here

But if you try,

def meth arg
  C = arg
end
# then 
# SyntaxError: dynamic constant assignment
# C = arg
#   ^

Comments

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.