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!