2010-09-08 19 views
9

¿Puedo crear un hash de Ruby desde un bloque?Create hash using block (Ruby)

Algo como esto (aunque esto específicamente no está funcionando):

foo = Hash.new do |f| 
    f[:apple] = "red" 
    f[:orange] = "orange" 
    f[:grape] = "purple" 
end 
+0

Por curiosidad, ¿está probando este enfoque porque lo hace al crear nuevos objetos ActiveRecord? –

Respuesta

12

No puedo entender por qué

foo = { 
    :apple => "red", 
    :orange => "orange", 
    :grape => "purple" 
} 

no funciona para usted?

Yo quería publicar esto como comentario, pero no pude encontrar el botón, lo siento

+0

Usted plantea un buen punto :) – user94154

+1

necesita 50 reputación antes de poder publicar comentarios. Deberías poder dejar comentarios ahora tu respuesta ha sido actualizada. – mikej

+0

gracias, supongo que debería leer las reglas primero: D – gkaykck

17

En Ruby 1.9 (o con ActiveSupport cargado, por ejemplo, en los carriles), puede utilizar Object#tap, por ejemplo:

foo = Hash.new.tap do |bar| 
    bar[:baz] = 'qux' 
end 

puede pasar de un bloque a Hash.new, pero que sirve para definir los valores por defecto:

foo = Hash.new { |hsh, key| hsh[key] = 'baz qux' } 
foo[:bar] #=> 'baz qux' 

Por lo que vale la pena, estoy asumiendo que usted tiene un propósito más grande en mente con este bloque de cosas. La sintaxis { :foo => 'bar', :baz => 'qux' } puede ser todo lo que realmente necesita.

+0

Tengo un archivo de dispositivo que es más o menos un montón de llamadas al método de creación ActiveRecord. Quería hacer las paces para la legibilidad. – user94154

3

¿Qué hay de malo en

foo = { 
    apple: 'red', 
    orange: 'orange', 
    grape: 'purple' 
} 
4

Pasando a un bloque Hash.new especifica qué es lo que sucede cuando se solicita una clave inexistente.

foo = Hash.new do |f| 
    f[:apple] = "red" 
    f[:orange] = "orange" 
    f[:grape] = "purple" 
end 
foo.inspect # => {} 
foo[:nosuchvalue] # => "purple" 
foo # => {:apple=>"red", :orange=>"orange", :grape=>"purple"} 

Como buscar una tecla se inexistentes sobre-escribir los datos existentes para :apple, :orange y :grape, usted no quiere que esto suceda.

Aquí está el enlace al Hash.new specification.

0

Como han mencionado otros, la sintaxis hash simple puede proporcionarle lo que desea.

# Standard hash 
foo = { 
    :apple => "red", 
    :orange => "orange", 
    :grape => "purple" 
} 

Pero si se utiliza el "toque" o hash con un método de bloques, se obtiene cierta flexibilidad adicional si es necesario. ¿Qué sucede si no queremos agregar un artículo a la ubicación de Apple debido a alguna condición? Ahora podemos hacer algo como lo siguiente:

# Tap or Block way... 
foo = {}.tap do |hsh| 
    hsh[:apple] = "red" if have_a_red_apple? 
    hsh[:orange] = "orange" if have_an_orange? 
    hsh[:grape] = "purple" if we_want_to_make_wine? 
}