Almost all decent resources about OOP in Ruby state the existence of access modifiers - keywords public
, private
and protected
- and show how to properly use them. Fewer go to the extent of explaining that these modifiers are not keywords, but are actual methods and that calling them modifies visibility of all methods defined in the future in this particular class. However, I couldn't find any information about how they actually do that. Do they change a special internal variable, or do they alter properties of current scope/binding, or do they set some specific interpreter flag, or... or what?
I've done a little research on my own, but it left me even more confused than before. Consider the following code snippet:
class Test
public
define_method :public_define_method do
puts 'Public define_method'
end
private
define_method :private_define_method do
puts 'Private define_method'
end
public
def public_def
puts 'Public def'
end
private
def private_def
puts 'Private def'
end
end
t = Test.new
t.public_define_method
t.private_define_method
t.public_def
t.private_def
#Output:
#> Public define_method
#> Private define_method
#> Public def
#> sandbox.rb:29:in `<main>': private method `private_def' called for #<Test:0x00000001cdfd38> (NoMethodError)
I always thought as def
as a sort of optimized syntactic sugar for define_method
with an additional quirk of creating new variable visibility scope, but, obviously, there seems to be more to it - methods created with def
are affected by private
/public
modifiers, while those created with define_method
are not. Furthermore, define_method
doesn't have any arguments related to changing method's visibility, which led me to the conclusion that information about it must be stored in classes, not methods themselves - and so should be the flag set by access modifiers. But why then def
so differs from define_method
? What happens in the background? Does it check the flag set by access modifier methods and then adds itself into some special hidden register of class' private/protected methods?..
In short, I'm very confused and would be very glad if comeone could please clarify the issue. Thanks in advance!