Shortcut for assigning instance variables

I am following the Codecademy Ruby course, 85% done.

Again and again, he asks you to create a class and pass some parameters and make them instance variables, for example:

class Computer def initialize(username, password) @username = username @password = password end end 

Each time, it asks you to do the same instance variables as the parameters you passed.

This made me wonder if there is a Ruby way to handle this automatically, eliminating the need to type it all on my own every time.

I know what you can do

 class Computer def initialize(username, password) @username, @password = username, password end end 

but it almost doesn't print.

I did a few searches and found that you can create a set of "getters" using attr_reader , for example

 class Song attr_reader :name, :artist, :duration end aSong = Song.new("Bicylops", "Fleck", 260) aSong.artist # "Fleck" aSong.name # "Bicylops" aSong.duration # 260 

But as far as I can tell, this is not what I am looking for. I am not trying to automatically create getters and / or setters. What I'm looking for would be something like this

 class Person def initialize(name, age, address, dob) #etc # assign all passed in parameters to equally named instance variables # for example assign_all_parameters_to_instance # name, age, address and dob would now be accessible via # @name, @age, @address and @dob, respectively end end 

I was looking for a ruby ​​shortcut to assign instance variables and so, but could not find the answer.

Is it possible? If so, how?

+5
source share
4 answers
 Person = Struct.new(:name, :artist, :duration) do # more code to the Person class end 

Another option is to pass the Hash / keyword of the variables and use something like ActiveModel :: Model https://github.com/rails/rails/blob/master/activemodel/lib/active_model/model.rb#L78-L81

 def initialize(params={}) params.each do |attr, value| self.instance_variable_set("@#{attr}", value) end if params end 
+6
source

First of all, your second block with the attr_reader set attr_reader not work. Since you provide 3 default arguments for the initialize method, which takes 0 arguments.

The answer to your question is no, there is no such method unless you yourself define it using metaprogramming.

+1
source

assign_all_parameters_to_instance cannot exist as you would like. He must have access to his local variables or caller parameters, which is very inconvenient, and encapsulation method violation.

However, you can simply create a suitable initialize method:

 class Module private def trivial_initializer(*args) module_eval(<<-"HERE") def initialize(#{args.join(', ')}) #{args.map {|arg| "@#{arg} = #{arg}" }.join("\n")} end HERE end end class Computer trivial_initializer :username, :password end Computer.new('jwm', '$ecret') # => #<Computer:0x007fb3130a6f18 @username="jwm", @password="$ecret"> 
+1
source

I used this https://www.safaribooksonline.com/library/view/ruby-cookbook/0596523696/ch10s09.html and it worked fine for me.

I just had to replace eval(var, binding) with eval(var.to_s, binding) .

So finally:

 class Object private def set_instance_variables(binding, *variables) variables.each do |var| instance_variable_set("@#{var}", eval(var.to_s, binding)) end end end class RGBColor def initialize(red=0, green=0, blue=0) set_instance_variables(binding, *local_variables) end end RGBColor.new(10, 200, 300) # => #<RGBColor:0xb7c22fc8 @red=10, @blue=300, @green=200> 
0
source

Source: https://habr.com/ru/post/1207987/


All Articles