2009-11-25 13 views
8

Estoy aprendiendo Ruby. Mi fondo es C++/Java/C#. En general, me gusta el idioma, pero estoy un poco confundido acerca de por qué hay tantas maneras diferentes de lograr lo mismo, cada una con su propia semántica ligeramente diferente.¿Por qué hay tantas formas ligeramente diferentes de hacer lo mismo en Ruby?

Tome la creación de cadenas, por ejemplo. Puedo usar '', "", q%, Q% o solo% para crear cadenas. Algunas formas admiten la interpolación. Otros formularios me permiten especificar los delimitadores de cadena.

¿Por qué hay cinco formas de crear cadenas literales? ¿Por qué alguna vez usaría cadenas no interpoladas? ¿Qué ventaja tiene la sintaxis% sobre los literales entre comillas?

Sé que debe haber valor en la redundencia en Ruby, pero mis ojos no entrenados no lo están viendo claramente. Por favor iluminame.

Respuesta

15

¿Por qué alguna vez usaría cadenas sin interpolación?

Cuando no desea la interpolación, por supuesto. Por ejemplo, tal vez que estés dar salida a parte de la documentación sobre la interpolación de cadenas:

'Use #{x} to interpolate the value of x.' 
=> "Use #{x} to interpolate the value of x." 

Qué ventaja tiene la sintaxis% tiene más de literales citados?

permite escribir cadenas de forma más natural, sin las comillas, o cuando no se desea escapar de muchas cosas, de forma análoga a C# 's literal-prefijo @.

%{The % syntax make strings look more "natural".} 
=> "The % syntax makes strings look more \"natural\"." 

%{<basket size="50">} 
=> "<basket size=\"50\">" 

hay muchas otras -notations%:

%w{apple banana #{1}cucumber} # [w]hitespace-separated array, no interpolation 
=> ["apple", "banana", "\#{1}cucumber"] 

%W{apple banana #{1}cucumber} # [W]hitespace-separated array with interpolation 
=> ["apple", "banana", "1cucumber"] 

# [r]egular expression (finds all unary primes) 
%r{^1?$|^(11+?)\1+$} 
=> /^1?$|^(11+?)\1+$/ 

(1..30).to_a.select{ |i| ("1" * i) !~ %r{^1?$|^(11+?)\1+$} } 
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] 

%x{ruby --version} # [s]hell command 
=> "ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]\n" 

También hay %s (para los símbolos) y algunos otros.

¿Por qué hay cinco formas de crear cadenas literales?

Esto no es terriblemente inusual. Considere C#, por ejemplo, que tiene varias formas diferentes de generar cadenas: new String(); ""; @""; StringBuilder.ToString(), et cetera.

+1

"natural" es muy subjetivo. "terriblemente inusual" no es una motivación para crear una función de idioma. – skrat

+1

"natural" es muy subjetivo, pero "menos y más caracteres fácilmente tipados para decir exactamente lo mismo" no lo es, y es una muy buena motivación para crear una función de idioma. –

1

Mucha de la sintaxis de Ruby se deriva de Perl, como usar q para citar algunas palabras en una cadena. Esa es probablemente la razón principal para una variedad tan grande.

3

No soy un experto en Ruby, pero ¿alguna vez has escuchado el término "azúcar sintáctico"? Básicamente, algunos lenguajes de programación ofrecen una sintaxis diferente para lograr la misma tarea. Algunas personas podrían encontrar una manera más fácil que otras debido a su experiencia previa en programación/sintaxis.

+0

De hecho. Aparentemente, Ruby está usando alias/sinónimos en más ocasiones. Por ejemplo, la cantidad de elementos en una matriz se puede recuperar con 'count',' length', o 'size'. Diferentes palabras para el mismo atributo de una matriz, pero con esto, Ruby le permite elegir la palabra más adecuada para su código: ¿desea el _número_ de elementos que está recopilando, la _ longitud_ de una matriz o el _ tamaño actual de la estructura. Básicamente, son todos iguales, pero elegir la palabra correcta puede hacer que su código sea más fácil de leer, lo cual es una buena propiedad del lenguaje. –

2

En la mayoría de las situaciones, terminará usando delimitadores de cadena normales. La principal diferencia entre comillas simples y dobles es que las comillas dobles le permiten interpolar variables.

puts 'this is a string' 
# => this is a string 
puts "this is a string" 
# => this is a string 
v = "string" 
puts 'this is a #{v}' 
# => this is a #{v} 
puts "this is a #{v}" 
# => this is a string 

%q y %Q son útiles cuando no se puede utilizar comillas porque son parte de la cadena interna. Por ejemplo, usted podría terminar de escribir

html = %Q{this is a <img src="#{img_path}" class="style" /> image tag} 

En este caso, no se puede utilizar comillas como delimitadores a menos que quiera escapar delimitadores de atributos internos. Además, no puede usar comillas simples porque la variable img_path no se interpolará.

0

Utilizaría cadenas sin interpolación si su cadena contiene muchos caracteres especiales (como barras diagonales inversas, #{}, etc.) y no quiere escaparse de todas.

Utilizaría diferentes delimitadores si su cadena contiene una gran cantidad de citas que de lo contrario tendría que escapar.

Utilizaría heredocs si sus cadenas tienen muchas líneas que harían que la sintaxis de cadena normal parezca difícil de manejar.

0

Ruby toma construcciones e ideas de muchos idiomas. Las dos influencias más aparentes son Smalltalk y Perl.

Dependiendo de su comodidad con Smalltalk o Perl, puede elegir diferentes constructos para hacer lo mismo.

1

Una razón más es un aumento de rendimiento menor para cadenas no interpoladas. Usar '' vs '' '' significa que Ruby no tiene que considerar qué hay dentro de la cadena. Por lo tanto, verá gente usando comillas simples para las teclas o símbolos de la matriz porque son más rápidos. Por lo que vale, incluiré un pequeño punto de referencia.

require 'benchmark' 

Benchmark.bmbm(10) do |x| 
    x.report("single-quote") do 
    for z in 0..1000000 
     zf = 'hello' 
    end 
    end 

    x.report("double-quote") do 
    for z in 0..1000000 
     zf = "hello" 
    end 
    end 

    x.report("symbol") do 
    for z in 0..1000000 
     zf = :hello 
    end 
    end 
end 

rendimientos:

Rehearsal ------------------------------------------------ 
single-quote 0.610000 0.000000 0.610000 ( 0.620387) 
double-quote 0.630000 0.000000 0.630000 ( 0.627018) 
symbol   0.270000 0.000000 0.270000 ( 0.309873) 
--------------------------------------- total: 1.580000sec 
0

A lo largo de las líneas de la respuesta de Juan: En los cortes rápidos, a menudo terminan corriendo un Perl o sed de una sola línea con la sintaxis grep desde dentro de mi guión rubí. Ser capaz de usar la sintaxis de tipo %[ ] significa que puedo simplemente copiar y pegar mi expresión regular desde el terminal

0

La pregunta original es por qué hay tantas maneras diferentes de hacer las cosas en Ruby.

A veces las diferentes cosas son sensatas: las citas son un buen caso en que un comportamiento diferente requiere una sintaxis diferente - no/interpolación, caracteres de comillas alternativas, etc. - y accidence histórico provoca sinónimos como% x() vs ``, tanto en Perl.

El problema de sinónimo - [] .size [] .length [] .count - parece un intento de ayudar en un mundo donde el lenguaje es demasiado aleatorio para que los IDE puedan ayudar: el parche de mono y el La combinación extraña de tipificación estricta pero dinámica hace que los errores de tiempo de ejecución sean una parte inevitable y frustrante de la codificación, por lo que la gente trata de reducir el problema mediante el suministro de sinónimos. Desafortunadamente, terminan confundiendo a los programadores que están acostumbrados a diferentes métodos haciendo cosas diferentes.

La cuestión 'de manera similar, pero no del todo', por ejemplo ...

$ ruby -le 'e=[]; e << (*[:A, :B])' 
-e:1: syntax error, unexpected ')', expecting :: or '[' or '.' 
$ ruby -le 'e=[]; e << *[:A, :B]' 
-e:1: syntax error, unexpected * 
$ ruby -le 'e=[]; e.push(*[:A, :B])' 
$ 

... sólo puede realmente ser visto como un defecto. Cada idioma los tiene, pero generalmente son más arcanos que esto.

Y luego está el sencillo y arbitrario error de "uso en lugar de aumentar a menos que esté volviendo a lanzar una excepción" en los estándares de codificación de Rubocop.

Hay algunas partes buenas en Ruby, pero en realidad, prefiero codificar en algo mejor fundado.

Cuestiones relacionadas