Given this basic class in Ruby:
class TestClass
def initialize(name)
@name = name
end
end
How do I then access the instance variable name directly from within the initialize method without creating a getter function? is this even possible? (i.e. using dot notation) or does the initialize method cease to exist once a class is instantiated, hence the need to define a getter method?
I think what I'm trying to ask is initialize a class or instance method?
The "getter method" is defined so that you can use the variable from outside the class:
class TestClass
attr_reader :name
def initialize(name)
@name = name
end
end
# TestClass.new('Ben').name # => 'Ben'
If you don't need to access it from outside the class, you can just use @name:
class TestClass
def initialize(name)
@name = name
end
def greet
puts "Hello, %s" % @name
end
end
# TestClass.new('Ben').greet # outputs: Hello, Ben
You can use the @name inside initialize:
class TestClass
def initialize(name)
@name = name
puts "Name backwards: %s" % @name.reverse
end
end
# TestClass.new('Ben') # outputs neB
Initialize is a special method, when you define initialize instance method, it is automatically marked private. The class method new calls it after creating an instance of your class.
Nothing stops you from calling private methods from inside the class:
class TestClass
def initialize(name)
@name = name
puts "Name is now %s" % @name
end
def flip_name
initialize(@name.reverse)
end
end
# t = TestClass.new('Ben') # outputs "Name is now Ben"
# t.flip_name # outputs "Name is now neB"
# t.instance_variable_get(:@name) # => 'neB'
The flip_name method that calls initialize works just fine, but of course this is quite unconventional and almost never used, because it does not make much sense.
It's possible to call private methods from outside the class using send:
# t.send(:initialize, 'Bill') # outputs "Name is now Bill"
# t.instance_variable_get(:@name) # => 'Bill'
Without send, you get NoMethodError:
> t.initialize('Jack')
NoMethodError: private method `initialize' called for #<TestClass:0x00007fa2df8e4570>
Ruby 1.9 beta releases changed send to act like public_send does today, allowing access to only public methods and there was going to be funccall for calling private methods if you really want to, for unit testing purposes for example. I think it caused too much compatibility issues and the change was reverted.
So in conclusion, yes, you can call initialize again and it does not cease to exist, but it is almost never done because it makes very little sense. To access instance variables from inside the class, you use @ notation like @name, to access them from outside of the class, you define a getter.
Yes, there is a way. But it's not a traditional one. It's more like querying the object to know
TestClass.new("foo").instance_variable_get(:@name)
=> "foo"
The initialize method does not "cease to exsist". It's executed, that's it. What your method do, in your case, is that the variable is set.
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