class Example
private
def example_test
puts 'Hello'
end
end
e = Example.new
e.example_test
Это, конечно, не будет работать, потому что мы указали явный получатель - экземпляр Example (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.
EDIT:
Спасибо за все ответы. Собрав их все вместе, я смог (наконец) ухватиться за очевидное (и не столь очевидное для кого-то, кто никогда не видел таких вещей, как Руби): что self
само по себе может быть
явный и неявный получатель, и это имеет значение. Таким образом, есть два правила, если вы хотите вызвать закрытый метод: self
должен быть неявным получателем, и это self должно быть экземпляром текущего класса (Example
в этом случае - и это имеет место только когда self, если внутри определение метода экземпляра во время выполнения этого метода). Пожалуйста, поправьте меня, если я ошибаюсь.
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 Trails: это может быть полезно - http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby