class Example
private
def example_test
puts 'Hello'
end
end
e = Example.new
e.example_test
Это, конечно, не сработает, потому что мы указали явный получатель - экземпляр примера (e
), а это противоречит "приватному правилу".
Но я не могу понять, почему в Ruby нельзя сделать так:
class Foo
def public_m
self.private_m # <=
end
private
def private_m
puts 'Hello'
end
end
Foo.new.public_m
Текущий объект внутри определения метода public_m
(то есть self
) является экземпляром Foo. Так почему не разрешено? Чтобы исправить это, я должен изменить self.private_m
только на private_m
. Но почему это отличается, разве self
не является экземпляром Foo внутри public_m
? И кто является получателем голого слова private_m
звонка? Разве это не self
- то, что на самом деле вы опускаете, потому что Ruby сделает это за вас (вызовет private_m для себя)?
Надеюсь, я не слишком запутался, я все еще новичок в Ruby.
РЕДАКТИРОВАТЬ: Спасибо за все ответы. Собрав их все вместе, я смог (наконец-то) понять очевидное (и не столь очевидное для тех, кто никогда не видел таких вещей, как Ruby): что self
сам по себе может быть явным и неявным получателем, и это имеет значение. Таким образом, есть два правила, если вы хотите вызвать закрытый метод: self
должен быть неявным получателем, и это self должно быть экземпляром текущего класса (в этом случае Example
- и это имеет место только тогда, когда self if находится внутри определения метода экземпляра, во время выполнения этого метода). Пожалуйста, поправьте меня, если я ошибаюсь.
class Example
# self as an explicit receiver (will throw an error)
def explicit
self.some_private_method
end
# self as an implicit receiver (will be ok)
def implicit
some_private_method
end
private
def some_private_method; end
end
Example.new.implicit
Сообщение для всех, кто смог найти этот вопрос во время поиска в Google: это может быть полезно — http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby