2012-04-24 26 views
6

¿Hay alguna herramienta de Ruby que me permita cargar un archivo de abreviaturas en el formato de (Abreviado => Abr)? Entonces necesito leer cada palabra de otro archivo. Si la palabra coincide con la palabra en las abreviaturas, necesito cambiarla a la palabra abreviada. Creo que puedo usar Hash, pero no sé cómo cargarlo desde un archivo.Ruby: ¿Cómo cargar un hash desde un archivo?

Respuesta

21

YAML es un formato muy universal para almacenar datos de una manera que se puede transferir entre aplicaciones y lenguajes de programación. JSON es otra alternativa, que es muy común en los sitios web.

Uso YAML para cosas como archivos de configuración porque es muy fácil de leer y modificar. Por ejemplo, esta estructura Ruby:

irb(main):002:0> foo = { 'a' => 1, 'b' => [2, 3], 'c' => { 'd' => 4, 'e' => 5 } } 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

Parece que este cuando se convierte en YAML:

irb(main):003:0> puts foo.to_yaml 
--- 
a: 1 
b: 
- 2 
- 3 
c: 
    d: 4 
    e: 5 

usted podría ahorrar que en un archivo:

File.open('foo.yaml', 'w') { |fo| fo.puts foo.to_yaml } 

y leer de nuevo en:

bar = YAML.load_file('foo.yaml') 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

Similarl Y, utilizando JSON:

puts foo.to_json 
{"a":1,"b":[2,3],"c":{"d":4,"e":5}} 

puede guardar el JSON a un archivo como lo haría con YAML y vuelva a cargar y convertirlo de nuevo en el hash. Es una sintaxis poco diferente, sin embargo:

irb(main):011:0> File.open('foo.json', 'w') { |fo| fo.puts foo.to_json } 
nil 
irb(main):012:0> bar = JSON.parse(File.read('foo.json')) 
{ 
    "a" => 1, 
    "b" => [ 
     [0] 2, 
     [1] 3 
    ], 
    "c" => { 
     "d" => 4, 
     "e" => 5 
    } 
} 

La gran victoria es ya sea con cualquier idioma que pueda leer YAML o JSON puede leer los archivos y el uso de los datos, ya sea leyendo o escribiendo.

Hacer la sustitución de cadena es muy fácil una vez que tiene un hash, porque el gsub de Ruby String comprende hash. Esto es de the docs:

Si el segundo argumento es un hash, y el texto que coincide es una de sus claves, la valor correspondiente es la cadena de reemplazo.

Esto significa que usted puede hacer algo como esto:

foo = 'Jackdaws love my giant sphinx of quartz' 
bar = { 'quartz' => 'rosy quartz', 'sphinx' => 'panda' } 
foo.gsub(Regexp.union(bar.keys), bar) 
"Jackdaws love my giant panda of rosy quartz" 

Usted tiene que estar atento a las colisiones límite de palabra que hace la sustitución, pero la bandera \b en un patrón puede ser de ayuda. Hacer que funcione es un ejercicio para el lector.

+0

Aunque esta es una buena explicación, yo diría que traer yaml o json solo complica un ejercicio simple. El archivo ya existe y ya es lo más simple posible: un archivo de texto delimitado, un registro por línea. Simplemente lea el archivo por línea, divídalo y construya el hash. – Jim

+0

¡Gracias! Funciona perfecto ahora. – user1128637

8

Ver Marshal.load y Marshal.dump.

Además, podría buscar serializar el hash en un archivo yaml y luego leerlo/guardarlo nuevamente a través de YAML.

+0

El formato 'Marshal' es (o puede ser) específico de la versión de Ruby en uso y no hay una manera (sana) de leer los datos de' Marshal' cuando las versiones no coinciden. Esto lo convierte en un mal formato para la serialización en el disco. –

0

Encontré este http://www.rubydoc.info/gems/bosh-director/1.1868.0/Bosh%2FDirector%2FConfig.load_hash después de buscar cómo cargar hashes yo mismo.

mi ejemplo es cuando se trata de MongoDB en una aplicación de Rails.

Así que establecí un método de inicialización para obtener la colección con la que voy a trabajar.

def initialize @collection = self.class.collection end

self.class aquí es la clase que estoy. La gente que vamos a utilizar como ejemplo.

el el método de carga es la siguiente

def load_collection(file_path) 
    hash_values = self.class.load_hash(file_path) 
    @collection.insert_many(hash) 
end 

dentro de un binding.pry

[1] pry(#<People>)> file_path 
=> "people_results.json" 
[2] pry(#<People>)> hash 
=> [{"number"=>0, "first_name"=>"SHAUN", "last_name"=>"JOHNSON", "gender"=>"M", "group"=>"15 to 19", "secs"=>1464}, {"number"=>1, "first_name"=>"TUAN", "last_name"=>"JOHNSON", "gender"=>"M", "group"=>"masters", "secs"=>3994}, {"number"=>2, "first_name"=>"EARLINE", "last_name"=>"BROWN", "gender"=>"F", "group"=>"masters", "secs"=>1415}... 
[3] pry(#<People>)> self 
=> #<People:0x007fc80301b5f8 @coll=#<Mongo::Collection:0x70248510355560 namespace=test.people>> 
[4] pry(#<People>)> self.class 
=> People 

Así que en este caso el método load_hash toma un parámetro, y en este caso i pasa en una json archivo con algunos datos. Luego inserto esos datos en mi colección.

Cuestiones relacionadas