Continuando con el meme "Características ocultas de ...", compartamos las características menos conocidas pero útiles del lenguaje de programación Ruby.
Intenta limitar esta discusión con el núcleo de Ruby, sin nada de Ruby on Rails.
Ver también:
- Características ocultas de C #
- Características ocultas de Java
- Características ocultas de JavaScript
- Características ocultas de Ruby on Rails
- Características ocultas de Python
(Por favor, solo una función oculta por respuesta).
Gracias
ruby
hidden-features
squadette
fuente
fuente
Respuestas:
De Ruby 1.9 Proc # === es un alias para la llamada Proc #, lo que significa que los objetos Proc se pueden usar en declaraciones de caso como esta:
fuente
Peter Cooper tiene una buena lista de trucos de Ruby. Quizás mi favorito es permitir que se enumeren artículos individuales y colecciones. (Es decir, trate un objeto que no sea de colección como una colección que contenga solo ese objeto). Se ve así:
fuente
items
es una cadena, no tiene que encerrarla con [* ...]. String.each no itera sobre los caracteres como algunos pueden esperar. Simplemente regresa al bloque.No sé qué tan oculto está esto, pero lo he encontrado útil cuando necesito hacer un hash de una matriz unidimensional:
fuente
Hash[ [["apple","red"], ["banana","yellow"] ]
produce el mismo resultado.Un truco que me gusta es usar el
*
expansor splat ( ) en objetos que no sean Arrays. Aquí hay un ejemplo en una coincidencia de expresión regular:Otros ejemplos incluyen:
fuente
text, number = *"text 555".match(/regexp/)[1..-1]
.text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Wow, nadie mencionó el operador de flip flop:
fuente
i == 3
cambia a falso después dei != 3
yi == 15
. Similar a un flip-flop: en.wikipedia.org/wiki/Flip-flop_%28electronics%29Una de las cosas interesantes de Ruby es que puede llamar a métodos y ejecutar código en lugares donde otros lenguajes estarían mal, como en definiciones de clase o método.
Por ejemplo, para crear una clase que tiene una superclase desconocida hasta el tiempo de ejecución, es decir, es aleatorio, puede hacer lo siguiente:
Esto usa el 1.9
Array#sample
método (solo en 1.8.7, verArray#choice
), y el ejemplo es bastante ingenioso, pero puedes ver el poder aquí.Otro buen ejemplo es la capacidad de poner valores de parámetros predeterminados que no son fijos (como suelen exigir otros idiomas):
Por supuesto, el problema con el primer ejemplo es que se evalúa en el momento de la definición, no en el momento de la llamada. Entonces, una vez que se ha elegido una superclase, se mantiene esa superclase por el resto del programa.
Sin embargo, en el segundo ejemplo, cada vez que llame
do_something_at
, laat
variable será la hora en que se llamó al método (bueno, muy, muy cerca de él)fuente
require 'activesupport'
Otra característica pequeña: convierte un
Fixnum
a cualquier base hasta 36:Y como ha comentado Huw Walters, la conversión a la inversa es igual de simple:
fuente
String#to_s(base)
se puede utilizar para convertir de nuevo a un número entero;"1001001100101100000001011010010".to_i(2)
,"499602d2".to_i(16)
etc todos devuelven el originalFixnum
.¡Hashes con valores predeterminados! Una matriz en este caso.
Muy útil en metaprogramación.
fuente
Descargue la fuente Ruby 1.9, y emítela
make golf
, luego puede hacer cosas como esta:Lee las
golf_prelude.c
cosas más ordenadas que se esconden.fuente
Otra adición divertida en la funcionalidad 1.9 Proc es Proc # curry, que le permite convertir un Proc que acepta n argumentos en uno que acepta n-1. Aquí se combina con el consejo Proc # === que mencioné anteriormente:
fuente
Operadores booleanos en valores no booleanos.
&&
y||
Ambos devuelven el valor de la última expresión evaluada.
Es por eso
||=
que actualizará la variable con la expresión de valor devuelto en el lado derecho si la variable no está definida. Esto no está explícitamente documentado, pero es de conocimiento común.Sin embargo, el
&&=
no es tan conocido.es equivalente a
Es muy útil para operaciones destructivas que no deberían continuar si la variable no está definida.
fuente
string &&= string + "suffix"
es equivalente astring = string && string + "suffix"
. Eso&&
y||
devolver su segundo argumento se discute en PickAx, p. 154 (Parte I - Facetas de Ruby, Expresiones, Ejecución condicional).La función Symbol # to_proc que proporciona Rails es realmente genial.
En vez de
Puedes escribir:
fuente
require 'activesupport'
ya que de ahí es de donde provienen la mayoría de estos ayudantes.Una última: en ruby puedes usar cualquier personaje que quieras delimitar cadenas. Toma el siguiente código:
Si no desea escapar de las comillas dobles dentro de la cadena, simplemente puede usar un delimitador diferente:
Además de evitar tener que escapar de los delimitadores, puede usar estos delimitadores para cadenas multilíneas más bonitas:
fuente
El uso del comando define_method para generar dinámicamente métodos es bastante interesante y no tan conocido. Por ejemplo:
El código anterior usa el comando 'define_method' para crear dinámicamente los métodos "press1" a través de "press9". En lugar de escribir los 10 métodos que contienen básicamente el mismo código, el comando definir método se usa para generar estos métodos sobre la marcha según sea necesario.
fuente
Use un objeto Range como una lista perezosa infinita:
Más información aquí: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
fuente
función_módulo
Los métodos de módulo que se declaran como module_function crearán copias de sí mismos como métodos de instancia privada en la clase que incluye el Módulo:
Si usa module_function sin ningún argumento, cualquier método de módulo que venga después de la declaración module_function se convertirá automáticamente en module_functions.
fuente
module_function
(segunda forma) es usarextend self
(que se ve muy bien: D)Inyección corta, como tal:
Suma de rango:
fuente
require 'backports'
:-)Advertencia: este artículo fue votado como el # 1 Hack más horrendo de 2008 , así que úsalo con cuidado. En realidad, evítalo como la peste, pero sin duda es Hidden Ruby.
Superators agrega nuevos operadores a Ruby
¿Alguna vez quisiste un operador de apretón de manos súper secreto para una operación única en tu código? ¿Te gusta jugar al golf en código? Pruebe operadores como - ~ + ~ - o <--- Ese último se usa en los ejemplos para invertir el orden de un elemento.
No tengo nada que ver con el Proyecto Superators más allá de admirarlo.
fuente
Llego tarde a la fiesta, pero:
Puede tomar fácilmente dos matrices de igual longitud y convertirlas en un hash con una matriz que proporciona las claves y la otra los valores:
(Esto funciona porque la matriz # zip "comprime" los valores de las dos matrices:
Y Hash [] puede tomar tal arreglo. He visto a personas hacer esto también:
Lo que produce el mismo resultado, pero el aplastamiento y el aplanamiento son totalmente innecesarios, ¿tal vez no estaban en el pasado?)
fuente
Hashes auto vivificantes en Ruby
Esto puede ser muy útil.
fuente
module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
Destruyendo una matriz
Dónde:
Con esta técnica, podemos usar una asignación simple para obtener los valores exactos que deseamos de una matriz anidada de cualquier profundidad.
fuente
Class.new()
Crea una nueva clase en tiempo de ejecución. El argumento puede ser una clase para derivar, y el bloque es el cuerpo de la clase. También es posible que desee mirar
const_set/const_get/const_defined?
para registrar su nueva clase correctamente, para queinspect
imprima un nombre en lugar de un número.No es algo que necesite todos los días, pero es bastante útil cuando lo necesita.
fuente
MyClass = Class.new Array do; def hi; 'hi'; end; end
parece ser equivalente aclass MyClass < Array; def hi; 'hi'; end; end
.crear una matriz de números consecutivos:
establece x en [0, 1, 2, 3, 4, 5]
fuente
*
operador splat ( ) básicamente llama deto_a
todos modos.Gran parte de la magia que ves en Rubyland tiene que ver con la metaprogramación, que es simplemente escribir código que escriba código para ti. Ruby
attr_accessor
,attr_reader
yattr_writer
son sencillas metaprogramming, en el que crean dos métodos en una sola línea, siguiendo un patrón estándar. Rails realiza una gran cantidad de metaprogramación con sus métodos de gestión de relaciones comohas_one
ybelongs_to
.Pero es bastante simple crear tus propios trucos de metaprogramación
class_eval
para ejecutar código escrito dinámicamente.El siguiente ejemplo permite que un objeto contenedor reenvíe ciertos métodos a un objeto interno:
El método
Wrapper.forwards
toma símbolos para los nombres de los métodos y los almacena en lamethods
matriz. Luego, para cada uno de los dados, usamosdefine_method
para crear un nuevo método cuyo trabajo es enviar el mensaje, incluyendo todos los argumentos y bloques.Un gran recurso para los problemas de metaprogramación es por qué "Lucky View Metaprogramming Clearing" de Lucky Stiff .
fuente
use cualquier cosa que responda a las
===(obj)
comparaciones de casos:Module
(y por tantoClass
),Regexp
,Date
, y muchas otras clases definen un método de instancia: === (otro), y todos se pueden usar.Gracias a Farrel por el recordatorio de
Proc#call
tener un alias comoProc#===
en Ruby 1.9.fuente
El binario "ruby" (al menos MRI) es compatible con muchos de los interruptores que hicieron que perl one-liners sea bastante popular.
Los significativos:
put
s al final de cada iteración del cicloAlgunos ejemplos:
Siéntase libre de google "ruby one-liners" y "perl one-liners" para obtener toneladas de ejemplos más útiles y prácticos. Básicamente, le permite usar ruby como un reemplazo bastante poderoso para awk y sed.
fuente
El método send () es un método de propósito general que se puede usar en cualquier clase u objeto en Ruby. Si no se reemplaza, send () acepta una cadena y llama al nombre del método cuya cadena se pasa. Por ejemplo, si el usuario hace clic en el botón "Clr", la cadena 'press_clear' se enviará al método send () y se llamará al método 'press_clear'. El método send () permite una forma divertida y dinámica de llamar a funciones en Ruby.
Hablo más sobre esta característica en Blogging Shoes: la aplicación Simple-Calc
fuente
Engaña a alguna clase o módulo diciéndole que ha requerido algo que realmente no ha requerido:
Esto es útil, por ejemplo, cuando se requiere A que a su vez requiere B pero no necesitamos B en nuestro código (y A tampoco lo usará a través de nuestro código):
Por ejemplo, Backgroundrb's
bdrb_test_helper requires
'test/spec'
, pero no lo usa en absoluto, así que en su código:fuente
Fixnum#to_s(base)
puede ser realmente útil en algún caso. Uno de estos casos es generar tokens aleatorios (pseudo) únicos al convertir un número aleatorio en una cadena utilizando la base de 36.Ficha de longitud 8:
Ficha de longitud 6:
fuente
Definir un método que acepte cualquier número de parámetros y simplemente los descarte todos
El
hello
método anterior solo necesita aparecerputs
"hello"
en la pantalla y llamarsuper
, pero dado que la superclasehello
define los parámetros, también debe hacerlo; sin embargo, dado que en realidad no necesita usar los parámetros en sí, no tiene que darles un nombre.fuente