Se ha dicho anteriormente que Ruby no tiene funciones, sólo métodos. Sin embargo existe más de una clase de métodos. En esta capítulo vamos a presentar el control de accesos.
Vamos a considerar lo que pasa cuando se define un método en el "nivel superior", no dentro de una clase. Se puede pensar que dicho método es análogo a una función de un lenguaje más tradicional como C.
Nuestro nuevo método parece que no pertenece a ninguna clase, pero de hecho Ruby se lo asigna a la clase Object, que es la superclase de cualquier otra clase. Como resultado de esto cualquier objeto es capaz de utilizar este método. Esto es cierto, pero existe un pequeño pero; es un método privado a cada clase. A continuación hablaremos más de lo que esto significa, pero una de sus consecuencias es que sólo se puede llamar de la siguiente formaruby> class Foo ruby| def fourth_power_of (x) ruby| square(x) * square(x) ruby| end ruby| end nil ruby> Foo.new.fourth_power_of 10 10000 |
Una disciplina mental común en la programación OO, que ya se señaló en un capítulo anterior, tiene que ver con la separación de la especificación y la implementación o qué tareas se supone que un objeto realiza y cómo realmente se consiguen. El trabajo interno de un objeto debe mantenerse, por lo general, oculto a sus usuarios; sólo se tiene que preocupar de lo que entra y lo que sale y confiar en que el objeto sabe lo que está realizando internamente. Así, es generalmente útil que las clases posean métodos que el mundo exterior no ve, pero que se utilizan internamente (y que pueden ser mejorados por el programador cuando desee, sin modificar la forma en que los usuarios ven los objetos de esa clase). En el trivial ejemplo que sigue, piénsese que engine es el motor interno de la clase.
ruby> class Test ruby| def times_two(a) ruby| print a," dos veces es ",engine(a),"\n" ruby| end ruby| def engine(b) ruby| b*2 ruby| end ruby| private:engine # esto oculta engine a los usuarios ruby| end Test ruby> test = Test.new #<Test:0x401c4230> ruby> test.engine(6) ERR: (eval):1: private method `engine' called for #<Test:0x401c4230> ruby> test.times_two(6) 6 dos veces es 12 nil |