2009-08-19 32 views
22

Viniendo de una larga historia de sintaxis de estilo C y ahora tratando de aprender Ruby (en Rails), he estado teniendo mi cuota de problemas con sus modismos y tal, pero hoy llegué a uno con el que no esperaba tener un problema y no puedo ver lo que sea que debe estar frente a mi cara.Error: Intento llamar al método privado

Tengo una clase Binaria que incluye un método privado para derivar un valor de URI a partir de un valor de ruta (uri y path son atributos de la clase). Estoy llamando desde dentro self.get_uri_from_path()Binary.upload(), pero me sale:

Attempt to call private method 

Un fragmento del modelo se parece a esto:

class Binary < ActiveRecord::Base 
    has_one :image 

    def upload(uploaded_file, save = false) 
    save_as = File.join(self.get_bin_root(), '_tmp', uploaded_file.original_path) 

    # write the file to a temporary directory 
    # set a few object properties 

    self.path = save_as.sub(Rails.root.to_s + '/', '') 
    self.uri = self.get_uri_from_path() 
    end 

    private 

    def get_uri_from_path 
    return self.path.sub('public', '') 
    end 
end 

estoy haciendo la llamada de forma incorrecta? ¿Me estoy perdiendo algo más que es aún más fundamental? El único lugar desde el que se llama al Binary.get_uri_from_path() es Binary.upload(). Esperaría poder llamar a un método privado desde la misma clase a menos que Ruby haga algo marcadamente diferente de otros idiomas que he usado.

Gracias.

Respuesta

43

No haga

self.get_uri_from_path() 

hacer

get_uri_from_path() 

Porque ...

class AccessPrivate 
    def a 
    end 
    private :a # a is private method 

    def accessing_private 
     a    # sure! 
     self.a   # nope! private methods cannot be called with an explicit receiver at all, even if that receiver is "self" 
     other_object.a # nope, a is private, you can't get it (but if it was protected, you could!) 
    end 
    end 

via

+1

Gracias. Un poco más de excavación me ayudó a entender las diferencias en los métodos privados de Ruby vs. otros idiomas. Simplemente no esperaba diferencias en ese nivel. –

+0

de nada. Es cierto que es un poco más complicado, pero en realidad tiene sentido después de un tiempo :) – marcgg

+0

Me parece que una gran cantidad de Ruby es excelente, lacónico, pero expresivo, pero definitivamente tengo que luchar en los deltas idiomáticos. :-) –

1

Creo que el idioma adecuado en este caso no es yo .get_uri_from_path() pero simplemente get_uri_from_path(). El yo es redundante. Notas adicionales: * self.path llama al método path en self, que presumiblemente se define en la clase padre. Si hubiera querido acceder directamente a la variable de instancia, podría haber dicho @path. (@ es el sigilo para las variables de instancia.) * Los paréntesis para los argumentos del método son opcionales, excepto cuando su ausencia podría causar ambigüedad. Podrías, si lo deseas, reemplazar get_uri_from_path() con get_uri_from_path. Esto contrasta con Javascript, donde una función sin par representa esa función como un valor en lugar de una aplicación de esa función.

+0

Sí, soy consciente de los parens opcionales, pero sigo viendo cosas sin ellos y no me gusta la ambigüedad. ¿Es una variable o es un método? Prefiero no tener que hacerme esa pregunta cada vez que lo veo. Tal vez eso sea más fácil con el tiempo. –

1

hay una diablos, aunque donde se puede llamar al método privado en cualquier situación, ese ser:

object.send(:private_method) 

Creo 1.9 tiene una aplicación diferente de este truco

+0

Sí, 1.9 tiene el envío! método. –

+0

En este punto, solo trato de aprender y entender las reglas. Me preocuparé por "romperlos" más tarde. :-) –

+0

1.9.2 no tiene el 'enviar!'método. Sin embargo, tiene 'enviar'. – Dex

Cuestiones relacionadas