I'm following Codecademy's Ruby course, about 85% done.
Over and over it asks you to create a class and pass in some parameters and make them instance variables, like this for example:
class Computer
def initialize(username, password)
@username = username
@password = password
end
end
Every time, it asks you to make the exact same instance variables as the parameters you passed in.
It made me wonder if there is a Ruby way to handle this automatically, removing the need to type it all out yourself every time.
I am aware you can do
class Computer
def initialize(username, password)
@username, @password = username, password
end
end
but that's hardly less typing.
I did some searching and found that you can create a set of 'getters' using attr_reader
like
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 that's not really what I'm looking for. I'm not trying to auto 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 did some searching for ruby shortcut for assigning instance variables and alike but couldn't find an answer.
Is this possible? If so, how?
Values can be assigned during the declaration or within the constructor. Instance variables can be accessed directly by calling the variable name inside the class. However, within static methods (when instance variables are given accessibility), they should be called using the fully qualified name.
In Objective-C, instance variables are commonly created with @propertys. An @property is basically an instance variable with a few extra bonus features attached. The biggest addition is that Objective-C will automatically define what's called a setter and a getter for you automatically.
We can modify the value of the instance variable and assign a new value to it using the object reference. Note: When you change the instance variable's values of one object, the changes will not be reflected in the remaining objects because every object maintains a separate copy of the instance variable.
Person = Struct.new(:name, :artist, :duration) do
# more code to the Person class
end
Your other option is to pass a Hash/keyword of variables instead 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
First of all, your second block with set of attr_reader
will not work. Because you are providing 3 arguments to default initialize
method, which accepts 0 arguments.
Answer to your question is no, there is no such method, unless you are going to define it yourself using metaprogramming.
assign_all_parameters_to_instance
can't exist the way you would want it to. It would need to have access to its caller's local variables or parameters, which is a very awkward thing to do, and a violation of method encapsulation.
However, you could just generate 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">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With