Antes de ler este artigo , pensei que o controle de acesso no Ruby funcionasse assim:
public
- pode ser acessado por qualquer objeto (por exemploObj.new.public_method
)protected
- só pode ser acessado de dentro do próprio objeto, bem como de qualquer subclasseprivate
- igual a protegido, mas o método não existe nas subclasses
No entanto, parece que protected
e private
age da mesma maneira, exceto pelo fato de que você não pode chamar private
métodos com um receptor explícito (ou seja self.protected_method
, funciona, mas self.private_method
não).
Qual o sentido disso? Quando existe um cenário em que você não deseja que seu método seja chamado com um receptor explícito?
ruby
language-design
access-specifier
Kyle Slattery
fonte
fonte
Object
tivessem permissão para chamar os métodos privados de todas as outras instânciasObject
, seria possível dizer coisas como5.puts("hello world")
.Respostas:
protected
métodos podem ser chamados por qualquer instância da classe de definição ou de suas subclasses.private
Os métodos podem ser chamados apenas de dentro do objeto de chamada. Você não pode acessar os métodos privados de outra instância diretamente.Aqui está um exemplo prático rápido:
some_method
não pode estarprivate
aqui. Deve serprotected
porque você precisa dele para receber receptores explícitos. Seus métodos típicos de ajudante interno geralmente podem ser,private
pois nunca precisam ser chamados assim.É importante observar que isso é diferente da maneira como o Java ou C ++ funciona.
private
no Ruby é semelhante aoprotected
Java / C ++, pois as subclasses têm acesso ao método. No Ruby, não há como restringir o acesso a um método de suas subclasses, como você pode fazerprivate
em Java.A visibilidade no Ruby é basicamente uma "recomendação", pois você sempre pode acessar um método usando
send
:fonte
private
vsprotected
tinha que fazer se uma subclasse poderia herdar um método, mas na verdade é sobre de onde o método pode ser chamado. Obrigado!send
?A diferença
self
. Mesmo você não pode ligarself.some_private_method
; você deve ligarprivate_method
com oself
implícito.self
receptor pode ser explícito,self.some_private_method
é permitido. (Qualquer outro receptor explícito ainda não será permitido, mesmo que o valor do tempo de execução seja o mesmo queself
.)Em Ruby, essas distinções são apenas conselhos de um programador para outro. Métodos não públicos são uma maneira de dizer "Eu me reservo o direito de mudar isso; não dependa disso". Mas você ainda recebe as tesouras afiadas
send
e pode chamar o método que desejar.Um breve tutorial
Então você pode executar
ruby dwarf.rb
e fazer o seguinte:fonte
age=
, pode (e precisa) chamá-loself
para separá-lo das variáveis locais.gimli.greet
,gimli
não é o chamador, mas o receptor. O chamador é o "ambiente de execução de nível superior", que na verdade é uma instância ad-hocObject
. Tente isto: #ruby -e 'p self; p self.class'
Métodos particulares em Ruby:
Se um método é privado no Ruby, ele não pode ser chamado por um receptor explícito (objeto). Só pode ser chamado implicitamente. Pode ser chamado implicitamente pela classe em que foi descrita, bem como pelas subclasses dessa classe.
Os exemplos a seguir ilustrarão melhor:
1) Uma classe Animal com método privado class_name
Nesse caso:
2) Uma subclasse de Animal chamada Amphibian:
Nesse caso:
Como você pode ver, os métodos privados podem ser chamados apenas implicitamente. Eles não podem ser chamados por receptores explícitos. Pelo mesmo motivo, métodos privados não podem ser chamados fora da hierarquia da classe de definição.
Métodos protegidos em Ruby:
Se um método estiver protegido no Ruby, ele poderá ser chamado implicitamente pela classe de definição e por suas subclasses. Além disso, eles também podem ser chamados por um receptor explícito, desde que o receptor seja próprio ou da mesma classe que o próprio:
1) Uma classe Animal com método protegido protect_me
Nesse caso:
2) Uma classe de mamíferos herdada da classe de animais
Nesse caso
3) Uma classe de anfíbios herdada da classe Animal (igual à classe de mamíferos)
Nesse caso
4) Uma classe chamada Árvore
Nesse caso:
fonte
Considere um método privado em Java. Pode ser chamado de dentro da mesma classe, é claro, mas também pode ser chamado por outra instância dessa mesma classe:
Então - se o chamador é uma instância diferente da minha mesma classe - meu método privado é realmente acessível a partir de "fora", por assim dizer. Na verdade, isso parece não ser tão privado.
Em Ruby, por outro lado, um método privado realmente deve ser privado apenas para a instância atual. É isso que a remoção da opção de um receptor explícito fornece.
Por outro lado, certamente devo dizer que é bastante comum na comunidade Ruby não usar esses controles de visibilidade, já que o Ruby oferece maneiras de contorná-los de qualquer maneira. Diferentemente do mundo Java, a tendência é tornar tudo acessível e confiar em outros desenvolvedores para não estragar tudo.
fonte
Parte da razão pela qual métodos privados podem ser acessados por subclasses no Ruby é que a herança do Ruby com classes é uma fina camada de açúcar sobre o Módulo inclui - no Ruby, uma classe, de fato, é um tipo de módulo que fornece herança, etc.
http://ruby-doc.org/core-2.0.0/Class.html
O que isso significa é que basicamente uma subclasse "inclui" a classe pai, para que efetivamente as funções da classe pai, incluindo funções privadas , sejam definidas na subclasse também.
Em outras linguagens de programação, chamar um método envolve transformar o nome do método em uma hierarquia de classes pai e encontrar a primeira classe pai que responde ao método. Por outro lado, em Ruby, enquanto a hierarquia da classe pai ainda está lá, os métodos da classe pai são incluídos diretamente na lista de métodos da subclasse definida.
fonte
Comparação de controles de acesso do Java contra o Ruby: Se o método for declarado privado em Java, ele poderá ser acessado apenas por outros métodos da mesma classe. Se um método é declarado protegido, ele pode ser acessado por outras classes existentes no mesmo pacote, bem como por subclasses da classe em um pacote diferente. Quando um método é público, é visível para todos. Em Java, o conceito de visibilidade do controle de acesso depende de onde essas classes se encontram na hierarquia de herança / pacote.
Enquanto no Ruby, a hierarquia de herança ou o pacote / módulo não se encaixa. É tudo sobre qual objeto é o receptor de um método.
Para um método privado em Ruby, nunca pode ser chamado com um receptor explícito. Podemos (apenas) chamar o método privado com um receptor implícito.
Isso também significa que podemos chamar um método privado de dentro de uma classe na qual ele é declarado, bem como de todas as subclasses dessa classe.
Você nunca pode chamar o método privado de fora da hierarquia de classes em que foi definido.
O método protegido pode ser chamado com um receptor implícito, como privado. Além disso, o método protegido também pode ser chamado por um receptor explícito (apenas) se o receptor for "próprio" ou "um objeto da mesma classe".
Resumo
Público: métodos públicos têm visibilidade máxima
Protected: O método protegido pode ser chamado com um receptor implícito, como privado. Além disso, o método protegido também pode ser chamado por um receptor explícito (apenas) se o receptor for "próprio" ou "um objeto da mesma classe".
Privado: para um método privado em Ruby, ele nunca pode ser chamado com um receptor explícito. Podemos (apenas) chamar o método privado com um receptor implícito. Isso também significa que podemos chamar um método privado de dentro de uma classe na qual ele é declarado, bem como de todas as subclasses dessa classe.
fonte
fonte