Ruby para novatos los operadores y sus métodos

Ruby es uno de los idiomas más populares utilizados en la web. Hemos comenzado una nueva serie de capturas de pantalla aquí en Nettuts + que te presentará a Ruby, así como a los excelentes marcos y herramientas que acompañan el desarrollo de Ruby. En esta lección, analizaremos a los operadores en Ruby, y por qué son diferentes de cualquier cosa que hayas visto antes..


Los operadores

Te has familiarizado con los operadores.

1 + 2 # 3 persona [: nombre] = "Joe"

Los operadores son cosas como el signo más (uno de los operadores aritméticos) o el signo igual (el operador de asignación). Estas cosas no parecen ser muy diferentes de las que usa en JavaScript, PHP o cualquier otro idioma. Pero, como la mayoría de Ruby, hay mucho más de lo que parece..

Aquí está el secreto: los operadores en Ruby son realmente llamadas a métodos. Prueba esto:

1. + (2) # 3

Aquí, estamos llamando a la + operador en el objeto 1, pasando en el objeto 2 como parámetro Recuperamos el objeto 3. Podemos hacer esto con cuerdas también:

name = "Joe" name. + ("Smith") # "Joe Smith", pero 'name' sigue siendo "Joe" name + = "Smith" # name ahora es "Joe Smith"

Como puede ver, podemos hacer concatenación de cadenas con el + método. Como beneficio adicional, ruby ​​define el operador + = basado en el operador + (nota: no puedes usar + = como método).

Como te darás cuenta, esto nos da un poder increíble. Podemos personalizar el significado de sumar, restar y asignar objetos en nuestras clases personalizadas. Vimos cómo funciona esto con las propiedades de los objetos en nuestra lección sobre las clases (definimos un propiedad y propiedad = método en la clase, y obtuve la sintaxis de azúcar esperada para usarlos). Lo que estamos viendo aquí es ir un paso más allá..


Construyendo nuestros propios métodos de operador

Intentemos crear uno de estos métodos nosotros mismos. Para este ejemplo, vamos a crear un objeto de refrigerador, al que podemos agregar cosas a través de + operador y sacar las cosas a través de la - operador.

Aquí está el comienzo de nuestra clase:

clase Frigorífico inicializar (bebidas = [], alimentos = []) @beverages = bebidas @foods = alimentos end def + (artículo) end def - (artículo) end end end

Nuestro inicializar La función es bastante simple: tomamos dos parámetros (que recurren a matrices vacías si no se da nada), y los asignamos a variables de instancia. Ahora, vamos a construir esas dos funciones:

def + (item) si item.is_a? Beverage @ beverages.push item else @ foods.push item end end

Esto es bastante simple. Cada objeto tiene una es un? Método que toma un solo parámetro: una clase. Si el objeto es una instancia de esa clase, devolverá verdadero; De lo contrario, devolverá falso. Entonces, esto dice que si el artículo que estamos agregando al refrigerador es un Bebida, lo agregaremos a la refrescos formación. De lo contrario, lo añadiremos a la @comida formación.

Eso es bueno; Ahora, ¿qué hay de sacar las cosas de la nevera? (Nota: este método es diferente del que se muestra en el video; esto muestra que este método de operador nos brinda una gran flexibilidad; en realidad son métodos normales con los que puede hacer cualquier cosa. Mejor versión del método, sin embargo, es más complejo.)

def - (item) ret = @ beverages.find do | bever | bever.name.downcase == item.downcase end return @ beverages.delete ret a menos que ret.nil? ret = @ foods.find do | food | food.name.downcase == item.downcase end @ foods.delete ret end

Esto es lo que está pasando cuando usamos el operador menos. El parámetro que toma es una cadena, con el nombre del elemento que estamos buscando (por cierto, crearemos el Bebida y Comida clases pronto). Comenzamos utilizando el encontrar Método que tienen los arreglos. Hay algunas maneras de usar este método; le estamos pasando un bloque; este bloque dice que estamos tratando de encontrar el elemento en la matriz que tiene una nombre propiedad que es la misma que la cadena que pasamos; Tenga en cuenta que estamos convirtiendo ambas cadenas en minúsculas, para estar seguros.

Si hay un elemento que coincide en la matriz, se almacenará en jubilado; de otra manera, jubilado estarán nulo. A continuación, devolveremos el resultado de @ bebida.delete ret, que elimina el elemento de la matriz y lo devuelve. Note que estamos usando un modificador de declaración al final de esa línea: hacemos esto a no ser que jubilado es nulo.

Usted podría preguntarse por qué estamos usando la palabra clave regreso Aquí, ya que no es obligatorio en Ruby. Si no lo usáramos aquí, la función aún no volvería, ya que hay más código para la función. Utilizando regreso aquí nos permite devolver un valor desde un lugar al que la función normalmente no devolvería.

Si no regresamos, eso significa que el artículo no fue encontrado en refrescos. Por lo tanto, asumiremos que está en @foods. Haremos lo mismo para encontrar el artículo en @foods y luego devolverlo.

Antes de probar esto, necesitaremos nuestro Comida y Bebidas clases:

clase Bebidas attr_accessor: nombre def inicializar nombre @name = nombre @time = Time.now end end clase Food attr_accessor: nombre def inicializar nombre @name = nombre @time = Time.now fin

Tenga en cuenta que en el video, no hice @nombre Accesible desde fuera del objeto. Aquí, estoy haciendo eso con attr_accessor: nombre, para que podamos comprobar el nombre de estos objetos cuando están dentro de un refrigerador.

Entonces, vamos a probarlo en irb; Comenzaremos solicitando el archivo que contiene el código; luego, prueba las clases; tenga en cuenta que he agregado saltos de línea a la salida para facilitar la lectura.

> require './lesson_6' => true> f = Fridge.new => # > f + Beverage.new ("agua") => [#]> f + Food.new ("bread") => [#]> f + Food.new ("huevos") => [#, # ]> f + Beverage.new ("jugo de naranja") => [#, # ]> f => #, # ], alimentos [#, # ]> f - "pan" => # > f => #, #], alimentos [#]

A medida que avanzamos, pueden ver cosas que se agregan a la refrescos y @foods matrices, y luego se elimina.


Obtener y establecer operadores

Ahora escribamos métodos para los operadores get y set que se usan con hashes. Has visto esto antes

person =  person [: name] = "Joe"

Pero, dado que estos operadores son métodos, podemos hacerlo de esta manera:

persona. [] = (: edad, 35) # para establecer persona. [] (: nombre) # para obtener

Está bien; Estos son métodos normales, con azúcar especial para su uso..

Vamos a intentarlo; haremos un Club clase. Nuestro club tiene miembros con diferentes roles. Sin embargo, podemos querer tener más de un miembro con un rol determinado. Entonces nuestro Club La instancia hará un seguimiento de los miembros y sus funciones con un hash. Si intentamos asignar un segundo miembro a un rol, en lugar de sobrescribir el primero, lo agregaremos.

class Club def initialize @members =  end def [] (role) @members [role] end def [] = (role, member) end end

La versión get es bastante simple; solo lo remitimos a la @members formación. Pero el set es un poco más complicado:

def [] == (role, member) if @members [role] .nil? @members [role] = miembro elsif @members [role] .is_a? String @members [role] = [@members [role], member] else @members [role] .push member end end end

Si esa función no se ha establecido, solo estableceremos el valor de esa clave para nuestro hash de miembro. Si se ha establecido como una cadena, queremos convertirlo en una matriz y colocar el miembro original y el nuevo miembro en esa matriz. Finalmente, si ninguna de esas opciones es verdadera, ya es una matriz, por lo que simplemente insertamos el miembro en la matriz. Podemos probar esta clase de esta manera:

c = Club.new c [: chair] = "Joe" c [: engineer] = "John" c [: engineer] = "Sue" c [: chair] # "Joe" c [: engingeer] # ["John ", "Demandar" ]

Hay que ir!


Otros operadores

Estos no son los únicos operadores con los que podemos hacer esto, por supuesto. Aquí está la lista completa:

  • Operadores aritméticos: + - * \
  • Obtener y establecer operadores: [] [] =
  • Operador de pala: <<
  • Operadores de comparación: == < > <= >=
  • Operador de igualdad de casos: ===
  • Operador poco inteligente: | & ^

Gracias por leer!

Si tienes alguna pregunta sobre esta lección, o cualquier otra cosa que hayamos discutido en Ruby, pregunta en los comentarios.!