Adding an instance variable to a class in Ruby
You can use attribute accessors:
class Array
attr_accessor :var
end
Now you can access it via:
array = []
array.var = 123
puts array.var
Note that you can also use attr_reader
or attr_writer
to define just getters or setters or you can define them manually as such:
class Array
attr_reader :getter_only_method
attr_writer :setter_only_method
# Manual definitions equivalent to using attr_reader/writer/accessor
def var
@var
end
def var=(value)
@var = value
end
end
You can also use singleton methods if you just want it defined on a single instance:
array = []
def array.var
@var
end
def array.var=(value)
@var = value
end
array.var = 123
puts array.var
FYI, in response to the comment on this answer, the singleton method works fine, and the following is proof:
irb(main):001:0> class A
irb(main):002:1> attr_accessor :b
irb(main):003:1> end
=> nil
irb(main):004:0> a = A.new
=> #<A:0x7fbb4b0efe58>
irb(main):005:0> a.b = 1
=> 1
irb(main):006:0> a.b
=> 1
irb(main):007:0> def a.setit=(value)
irb(main):008:1> @b = value
irb(main):009:1> end
=> nil
irb(main):010:0> a.setit = 2
=> 2
irb(main):011:0> a.b
=> 2
irb(main):012:0>
As you can see, the singleton method setit
will set the same field, @b
, as the one defined using the attr_accessor... so a singleton method is a perfectly valid approach to this question.
Ruby - Passing instance variables to a class from another
values_at
returns an array of values (see https://apidock.com/ruby/Hash/values_at
for explanation)
Change
@shipping_address = attributes.values_at(:shipping_address)
into
@shipping_address = attributes[:shipping_address]
And that way @shipping_address will contain an Address object, not an array that contains an Address object
how to change instance variables in class in ruby
In your Scenario this will be more convenient way to Handle it
class CoffeeMachine
attr_reader :water
def initialize(water=100)
@water = water
end
end
machine = CoffeeMachine.new
machine.water # 100
machine = CoffeeMachine.new(70)
machine.water # 70
How to add an instance variable to a class to back an added method?
Your instance_variable_set
is called when you call super_accessor_wow
during the class definition. No instance of the class exists yet. You create an instance of the class when you call new
. You could add your @crazy_var_name
initialization to the constructor, or you could define it in the greetings
method:
Put the default in a class variable, and initialize the instance variable in the constructor (be aware that this creates a constructor for your class, and if you then create your own constructor, it will override this one):
class Class
def super_accessor_wow(attr_name)
attr_name = attr_name.to_s
new_var_name = "@crazy_var_name"
new_var_name_default = "@#{new_var_name}"
module_eval(%Q/
#{new_var_name_default} = ["hi", "everyone"]
def initialize()
#{new_var_name} = #{new_var_name_default}
end
def super_#{attr_name}()
return @#{attr_name}
end
def super_#{attr_name}=(value)
@#{attr_name} = value
end
def greetings
return #{new_var_name}
end
/)
end
end
class Foo
super_accessor_wow(:bar)
end
foo1 = Foo.new()
foo1.super_bar = 1000
puts foo1.super_bar
puts foo1.greetings.inspect
puts Foo.class_variable_get('@@crazy_var_name').inspect
puts foo1.instance_variable_get('@crazy_var_name').inspect
Outputs:
1000
["hi", "everyone"]
["hi", "everyone"]
["hi", "everyone"]
Define it in the greetings
method:
class Class
def super_accessor_wow(attr_name)
attr_name = attr_name.to_s
new_var_name = "@crazy_var_name"
module_eval(%Q/
def super_#{attr_name}()
return @#{attr_name}
end
def super_#{attr_name}=(value)
@#{attr_name} = value
end
def greetings
#{new_var_name} = ["hi", "everyone"] unless #{new_var_name}
return #{new_var_name}
end
/)
end
end
class Foo
super_accessor_wow(:bar)
end
foo1 = Foo.new()
foo1.super_bar = 1000
puts foo1.super_bar
puts foo1.greetings.inspect
Outputs
1000
["hi", "everyone"]
Accessing instance variable in rails and ruby
Use attr_reader
to read the value of an instance variable
class Person
attr_reader :name
def initialize(name)
@name = name
end
end
john = Person.new("John")
john.name #=> "John"
attr_reader
adds a getter method to the class, in this case
def name
@name
end
Hope that helps!
Related Topics
Accessing Ruby Class Variables with Class_Eval and Instance_Eval
Best Way to Combine Fragment and Object Caching for Memcached and Rails
Best Way to Cache a Response in Sinatra
Ruby on Rails, Including a Module with Arguments
How to Remove/Disable Sign Up from Devise
What Are the Uppercase and Lowercase Rules of Ruby Method Name
Why Is This String Key in a Hash Converted to a Symbol
Rbenv Build Failed on Ubuntu 14.04
Mongodb and Mongoid in Production
When Is It Better to Use a Struct Rather Than a Hash in Ruby
Carrierwave Crop Specific Version
Augmenting a Model from an External Gem
How to Get Request.Uri in Model in Rails
Simple_Form: Remove Outer Label for an Inline Checkbox with Label
Bundle Install: Error: Failed to Build Gem Native Extension. Nio4R Gem