Problem
You're writing a class constructor that takes a lot of arguments, each of which is simply assigned to an instance variable.
class RGBColor(red=0, green=0, blue=0) @red = red @green = green @blue = blue end
You'd like to avoid all the typing necessary to do those variable assignments.
Solution
Here's a method that initializes the instance variables for you. It takes as an argument the list of variables passed into the initialize method, and the binding of the variables to values.
class Object private def set_instance_variables(binding, *variables) variables.each do |var| instance_variable_set("@#{var}", eval(var, binding)) end end end
Using this method, you can eliminate the tedious variable assignments:
class RGBColor def initialize(red=0, green=0, blue=0) set_instance_variables(binding, *local_variables) end end RGBColor.new(10, 200, 300) # => #
Discussion
Our set_ instance_variables takes a list of argument names to turn into instance variables, and a Binding containing the values of those arguments as of the method call. For each argument name, an eval statement binds the corresponding instance variable to the corresponding value in the Binding. Since you control the names of your own variables, this eval is about as safe as it gets.
The names of a method's arguments aren't accessible from Ruby code, so how do we get that list? Through trickery. When a method is called, any arguments passed in are immediately bound to local variables. At the very beginning of the method, these are the only local variables defined. This means that calling Kernel#local_variables at the beginning of a method will get a list of all the argument names.
If your method accepts arguments that you don't want to set as instance variables, simply remove their names from the result of Kernel#local_variables before passing the list into set_instance_variables:
class RGBColor def initialize(red=0, green=0, blue=0, debug=false) set_instance_variables(binding, *local_variables-['debug']) puts "Color: #{red}/#{green}/#{blue}" if debug end end RGBColor.new(10, 200, 255, true) # Color: 10/200/255 # => #
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration