example - json parse ruby
¿Cuál es la diferencia entre los métodos JSON.load y JSON.parse de Ruby lib? (4)
Desde el documento ruby puedo ver que load
método de load
toma un proc como arg mientras que el parse
no lo hace. ¿Hay alguna otra diferencia? Por ejemplo, cuando tengo una cadena de caracteres JSON, ¿qué método debo usar para convertirlo en un objeto Ruby?
load (source, proc = nil, options = {}) Cargue una estructura de datos ruby desde un origen JSON y devuélvala. Una fuente puede ser un objeto parecido a una cadena, un objeto similar a IO o un objeto que responde al método de lectura. Si se proporcionó proc, se llamará con cualquier objeto Ruby anidado como argumento recursivamente en primer orden de profundidad. Para modificar las opciones predeterminadas, pase también el argumento de opciones opcionales. Este método es parte de la implementación de la interfaz de carga / volcado de Marshal y YAML. También alias como: restaurar
analizar (origen, optos = {}) Analizar el origen del documento JSON en una estructura de datos de Ruby y devolverlo.
Otra diferencia más: diferentes opciones.
Ejemplo de uso común (note _keys
vs. _names
):
JSON.load ''{"key": "val"}'', symbolize_keys: true
=> {"key" => "val"} # parse option syntax silently ignored
JSON.parse ''{"key": "val"}'', symbolize_keys: true
=> {:key => "val"} # symbols, yay!
JSON.load ''{"key": "val"}'', symbolize_names: true
=> {:key => "val"} # using the correct syntax for load
Una diferencia clave es que JSON.load
no es seguro cuando se le da una entrada que no es de confianza (lo mismo se puede lograr con JSON.parse
, pero tiene valores predeterminados seguros). Esto se debe a que proporciona una forma de instanciar clases distintas de las clases de hash, cadena, matriz y número "normales":
class Foo
def self.json_creatable?
true
end
def self.json_create attributes
puts "called with #{attributes}"
end
end
JSON.parse(''{"json_class": "Foo"}'') #=> {"json_class"=>"Foo"}
mientras
JSON.load(''{"json_class": "Foo"}'')
called with {"json_class"=>"Foo"}
#=> nil
Esta diseñada para que usted implemente una serialización personalizada de datos, no debe usarse cuando se analizan datos de todo el mundo. ¿Por supuesto que necesitas implementar el json_creatable?
y los métodos json_create
para que esto logre realmente algo, pero ¿qué tan seguro está de que ninguna de sus dependencias hace esto o implementa method_missing
de tal manera que pueda ser mal utilizado? (Consulte, por ejemplo, los exploits Marshal.load
. Como resultado de esto, JSON.load
y JSON.parse
se JSON.parse
significativamente).
Siempre use JSON.parse
cuando trate con datos que no sean de confianza o a menos que necesite las capacidades adicionales de JSON.load
Una diferencia más es que JSON.load
analiza el valor único (no el objeto y no la matriz) de forma predeterminada.
JSON.load("false")
=> false
JSON.load("123")
=> 123
Pero JSON.parse
requiere que el quirks mode
esté habilitado para analizar dicho valor.
JSON.parse("false")
JSON::ParserError: 757: unexpected token at ''false''
JSON.parse("false", quirks_mode: true)
=> false
JSON#parse
analiza una cadena JSON en un Ruby Hash.
JSON.parse(''{"name": "Some Name"}'') # => {"name" => "Some Name"}
JSON#load
toma una cadena o IO (archivo, etc.) y la convierte en Ruby Hash / Array
JSON.load File.new("names.json") # => Reads the JSON inside the file and results in a Ruby Object.
JSON.load ''{"name": "Some Name"}'' # Works just like #parse
De hecho, convierte cualquier objeto que responde a un método #read
. Por ejemplo:
class A
def initialize
@a = ''{"name": "Some Name"}''
end
def read
@a
end
end
JSON.load(A.new) # => {"name" => "Some Name"}