Example:
class Parent
private
def self.static
…
end
end
class Child <Parent
def foo
# Invoke static() here
end
end
My question is about invoking the method static() from within foo, in
Ruby 1.9.3.
I found - by trial and error - that I can do it by
Parent::static
or
Parent.static
but I can not do it by simply calling
static
(I get an error message that ‘static’ is not found), and I wonder, why.
As far I understand, Ruby has the somewhat unusual approach to private
methods, by specifying that “a private method can be called only without
explicit receiver”.
Well - ‘Parent.static’ DOES have an explicit receiver, yet can be
called, and writing just ‘static’ does NOT have an explicit receiver,
but can not be called.
Could someone kindly help me out of this confusion?
You are missing some Ruby Logic in this place.
class Parent
private
def self.static
puts ‘Raja’
end
end
class Child <Parent
def foo
static
end
end
1)Parent.static # Raja
2)Child.new.foo
Second one doesn’t execute because static is the class method of Parent
class, that means static method is defined in a class for that Parent is
the object, for an example I would redefined the above class below in a
slightly different way so that you would understand
class Class
def static #Look at where this static method is defined
end #Not inside your parent class
end
Parent=Class.new do
end
class Child <Parent
def foo
static
end
end
So the above definition is equivalent of your above program, now
look at where static method is defined, Since Parent is the Object of
Class, Parent can access, but Object of Child can’t access because
method is not defined inside the parent class.
You said "Well - ‘Parent.static’ DOES have an explicit receiver, "
No, clearly not, the problem here is your static method scope is inside
the ‘class Class’, but you have given the scope of private inside the
Parent class, So it doesn’t matter, Ruby still remain the logic of
private method can’t be accessed with the help of explicit receiver.
Parent can access, but Object of Child can’t access because
method is not defined inside the parent class.
So, in my original example, why is it that I can invoke Parent.static
without getting an error?
The reason you can access because that method named ‘static’ is not
defined inside your parent class, it’s defined in the ‘class Class’, So
Parent is the object to that method,
you have defined the class this way
class Parent
private
def self.static
puts ‘Raja’
end
end
class Child <Parent
def foo
static
end
end
this is absolutely equivalent to
class Class
def static #Look at where this static method is defined
end #Not inside your parent class
end
class Parent
private
end
class Child <Parent
def foo
static
end
end
So you can use your Parent to access that static method, because static
is not defined inside your Parent class, instead Parent is the object of
class Class where your static method is defined.
Note : Every class name is the Object of ‘class Class’.
The reason you can access because that method named ‘static’ is not
defined inside your parent class, it’s defined in the ‘class Class’
I didn’t know that! How does this work, internally? If
class Foo
def self.f
end
end
is equivalent to
class Class
def f
end
and I have another class with the same class method, i.e.
class Bar
def self.f
end
end
this one must then end up as a instance method Class.f as well, so we
would have two different methods with the same name inside class Class.
How is this possible?
Yes, that’s the good question
There is something called singleton method, Have you heard about that?
For an example,
If you declared the method as given below,
class Raj
end
Obj=Raj.new
def obj.hi
puts ‘hi’
end
Then this method class can only be accessed by ‘obj’ object and not by
any other object of Raj class.
This is the same way the our discussed method declared too, for an
example,
class Raj
def self.hi
end
end
Now this hi method can only be accessed by object Raj not by any other
object, So the following class ‘Gopal’ can’t access that function,
class Gopal
end
Now you know Raj and Gopal both classes are objects are ‘class Class’,
but still hi method is only available to Raj not to Gopal because this
is similar to the singleton method which I have explained above. But If
you inherited the method Raj then Gopal too can access the method ‘hi’
in the same way Raj can access, for an example,
class Gopal<Raj
end
now hi method can be accessed by Gopal as well.
So, the “static” method is not added to the class Class, but as a
singleton method to a certain instance of class Class - i.e. that
instance which is associated to the class in which I define the “static”
method. Correct?
Ronald
You are correct with your idea, but there is no such concept called
static method in Ruby, because the particular method is always
associated with objects.