0

I don't know how exactly to word this, but I am trying to define many variables and then redefine them without rewriting each of the many variables and creating redundant code in each new block I write. The variables are defining array elements from multiple databases. Here is a downsized sample what I am working with:

def lots_of_vars(array)
  name = array[1]
  membership = array[2]
  spouse = array[3]
  ....
  lap12 = array[36]
end

def second_block
  #database1 => [ "Randy", true, "Nancy", 2, 17, false...
  lots_of_vars(database1)
  return unless membership
  puts "Lap progress for #{name} and #{spouse}: #{lap1}, #{lap2}... #{lap12}..."
end

def third_block
  #database2 => [ "Steven", true, nil, 0, 5, false...
  lots_of_vars(database2)
  return unless spouse.empty? or spouse.nil?
  puts "Weekly progress for #{name}: #{lap1}, #{lap5}, #{lap6}, #{lap10}..."
end

The second and third block need all the variables defined from the first block/method. But how do I pass all these variables? One example I read suggested I pass them all as parameters like:

def second_block(name, membership, spouse...)

but this would make just as much of a mess as defining each variable twice in both blocks. What is the simple, dry approach to such a situation? Please let me know if I need to clarify anything in my question, Thanks.

2 Answers 2

3

What you want is to create a Struct, which is a simple class to represent a datastructure. A struct will take its arguments in by position, which is exactly what you want, since you can splat the array into the method call (turn an array into an argument list)

So

Thing = Struct.new(:name, :membership, :spouse, :lap12)

array = ['Larry', 'gold', 'Sue', 2.2]
thing = Thing.new(*array)

#note that the splat (*) is equivalent to saying
# Thing.new(array[0], array[1], array[2], array[3])

thing.name # => "Larry"
thing.lap12 # => 2.2
Sign up to request clarification or add additional context in comments.

Comments

0

Definitely approach with struct is one of the best.

Also you could do something like that:

HERE BE DRAGONS, DON'T TRY IT AT HOME! :)

class Foo

  def lots_of_vars(array)
    name = array[0]
    email = array[1]
    description = array[2]

    binding
  end

  def bar
    array = ['Luke', '[email protected]', 'Lorem ipsum']
    eval('"My name is #{name}, email: #{email}, here is description: #{description}"', lots_of_vars(array))
  end

end

foo = Foo.new
foo.bar

For more details you could check this nice blog post about ruby's binding http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc

1 Comment

no problem, but please promise me that you won't use binding technique in your application ;)

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.