2017-03-28 1 views
2

Presque toutes les ressources décentes sur la POO dans Ruby indiquent l'existence de modificateurs d'accès - mots-clés public, private et protected - et montrent comment les utiliser correctement. Moins vont jusqu'à expliquer que ces modificateurs sont pas mots-clés, mais sont des méthodes réelles et que leur appel modifie la visibilité de toutes les méthodes définies dans le futur dans cette classe particulière. Cependant, je ne pouvais pas trouver des informations sur comment ils font réellement cela. Est-ce qu'ils modifient une variable interne spéciale, ou modifient-ils les propriétés de l'étendue/de la liaison en cours, ou définissent-ils un indicateur d'interpréteur spécifique, ou ... ou quoi?Que font exactement les méthodes "public", "private" et "protected"?

J'ai fait un peu de recherche par moi-même, mais cela m'a rendu encore plus confus qu'auparavant. Considérons l'extrait de code suivant:

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) 

J'ai toujours pensé que def comme une sorte de sucre syntaxique optimisé pour define_method avec une bizarrerie supplémentaire de créer une marge nouvelle visibilité variable mais, de toute évidence, il semble y avoir plus à lui - les méthodes créées avec def sont affectées par les modificateurs private/public, tandis que celles créées avec define_method ne le sont pas. En outre, tous les arguments liés à la modification de la visibilité de la méthode, ce qui m'a amené à la conclusion que les informations à ce sujet doivent être stockées dans les classes et non dans les méthodes elles-mêmes. Mais pourquoi alors def diffère donc de define_method? Que se passe-t-il en arrière-plan? Vérifie-t-il le drapeau défini par les méthodes de modificateur d'accès, puis ajoute lui-même dans un registre caché spécial des méthodes privées/protégées de la classe? ..

En bref, je suis très confus et serais très heureux si vous pouviez s'il vous plaît clarifier la question. Merci d'avance!

Répondre

1

Exactement?

publique http://apidock.com/ruby/Module/public

Sans argument, définit la visibilité par défaut pour les méthodes définies par la suite au public. Avec les arguments, définit les méthodes nommées pour avoir une visibilité publique.

Source:

static VALUE 
rb_mod_public(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PUBLIC); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PUBLIC); 
    } 
    return module; 
} 

privéhttp://apidock.com/ruby/Module/private

Sans argument, définit la visibilité par défaut par la suite méthodes définies à privé. Avec les arguments, définit les méthodes nommées à avoir une visibilité privée.

Source:

static VALUE 
rb_mod_private(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PRIVATE); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PRIVATE); 
    } 
    return module; 
} 

protégéhttp://apidock.com/ruby/Module/protected

Sans argument, définit la visibilité par défaut pour la suite méthodes définies à protéger. Avec les arguments, définit les méthodes nommées pour avoir une visibilité protégée.

source de

static VALUE 
rb_mod_protected(int argc, VALUE *argv, VALUE module) 
{ 
    secure_visibility(module); 
    if (argc == 0) { 
     SCOPE_SET(NOEX_PROTECTED); 
    } 
    else { 
     set_method_visibility(module, argc, argv, NOEX_PROTECTED); 
    } 
    return module; 
} 

Cela ne contribue pas vraiment avec des applications réelles pour ces informations, cependant. Vous pouvez trouver plus d'informations applicables dans le monde réel sur des questions comme What are the differences between "private", "public", and "protected methods"? et Why does Ruby have both private and protected methods?.

+0

Merci pour la réponse, mais ce n'est pas exactement ce que je cherche. Je sais déjà comment fonctionne l'encapsulation dans Ruby et les résultats de l'appel de ces méthodes, j'essaie de comprendre ce qu'ils font * sous le capot *. S'il vous plaît, relisez la question. Je ne connais pas beaucoup le C++, donc creuser seul le code source de l'interpréteur ne ferait que créer plus de confusion. Les extraits de code sont vraiment utiles, mais pourriez-vous nous en dire plus sur les fonctions de 'SCOPE_SET' et de' set_method_visibility'? Les effets 'public' /' protected'/'private' pourraient-ils être reproduits dans Ruby pur, par exemple, ou sont-ils codés en dur? Merci! – DeFazer