Search code examples
rubyinstance-variables

Shortcut to assigning instance variables


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?


Solution

  • 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