2012-08-12 6 views
5

Ich versuche, einen guten Ruby-Codierungsstil zu bekommen. Um zu verhindern, dass versehentlich eine lokale Variable mit dem gleichen Namen aufgerufen wird, verwende ich immer self.. Aber jetzt stolperte ich über diese:Aufruf einer privaten Methode xxx mit self.xxx() aus einer anderen privaten Methode resultierend in Fehler "private Methode` xxx 'genannt "

class MyClass < ActiveRecord::Base 
    before_validation :sanitize_user_data 

    private 

    def sanitize_user_data 
    self.sanitize_name # with ".self" it's a problem, without it's not! 
    end 

    def sanitize_name 
    unless self.name.nil? 
     self.name.gsub!(/\s+/, ' ') 
     self.name.strip! 
    end 
    end 
end 

Die obigen Code führt zu einem Fehler

private Methode sanitize_name genannt

aber wenn self. entfernen und nur mit sanitize_name, es funktioniert. Warum ist das?

Antwort

8

Dies geschieht, weil private Methoden können nicht mit einem expliziten Empfänger genannt werden, und zu sagen self.sanitize_name explizit das Objekt wird die Angabe (self), die sanitize_name erhalten sollten, anstatt sich auf die implizite Empfänger unter Berufung (die auch self).

Sie können dies nicht vermeiden, Sie müssen entweder einfach alt sanitize_name ohne einen expliziten Empfänger aufrufen, oder tun self.send(:sanitize_name). Ich bin mir nicht sicher, ob das explizite Spezifizieren von self wirklich "guter Stil" ist, aber das ist subjektiv. Wenn Sie sicherstellen möchten, sind Sie eine Methode, anstatt eine Variable aufrufen, fügen Sie Klammern:

def a; "method"; end 
a = "variable" 
a() #=> "method" 
a #=> "variable" 
+0

Vielen Dank für die Erklärung. Ich werde das im Hinterkopf behalten, aber ich denke, um es wirklich zu verstehen, müsste ich tief in Rubys Interna eindringen, oder? –

+3

@JoshuaMuheim Nicht unbedingt, es ist nur die Art, wie private Methoden funktionieren, indem man einen expliziten Empfänger verbietet, kann nicht von überall her aufgerufen werden, der implizite Empfänger ist nicht das selbe "Selbst", es hat nur den etwas unglücklichen Nebeneffekt, dich davon abzuhalten eine private Methode mit demselben expliziten Empfänger aufrufen wie der implizite Empfänger. –

+0

Okay, das ist interessant. Vielen Dank für die Erklärung. :) –

2

Warum ist das?

per definitionem. Private Methoden können nur von einer empfängerlosen Nachricht aufgerufen werden, das heißt Definition von was private bedeutet.

+0

+1 Kurz und gut. –