tamaño suma metodos hashes funciones declarar datos arreglos array agregar acceder ruby hash key symbols

ruby - suma - ¿Por qué double splat solo funciona con las teclas de símbolo?



suma de arreglos ruby (2)

El operador de doble splat ** solo parece funcionar con hashes cuyas claves son símbolos. No funcionará cuando una clave es una cadena, por ejemplo. Esto es cierto para ambas formas; para construcción:

def foo **; end foo(:a => 3) #=> nil foo("a" => 3) #=> ArgumentError: wrong number of arguments (1 for 0)

y destrucción:

def bar *; end bar(**{:a => 3}) #=> nil bar(**{"a" => 3}) #=> TypeError: wrong argument type String (expected Symbol)

¿Por qué se limita a las teclas de símbolos?

Puede estar relacionado con el hecho de que la notación de palabra clave con nombre a: 3 coincide con la sintaxis de azúcar para el hash con teclas de símbolos, pero como se vio anteriormente, el splat doble funciona con la notación de hash ordinaria :a => 3 , por lo que no estoy seguro sobre esto.


La respuesta corta: así es como se expresan en Ruby los argumentos de palabras clave, que se supone que debe capturar el operador de doble splat.

La respuesta larga: el operador de doble splat es para capturar palabras clave como se ve en esta respuesta: https://.com/a/18289218/3644699

Desde Ruby 2.0, Ruby soporta verdaderos argumentos de palabras clave. Mi conjetura es que en la implementación principal todavía se representan como Hashes cuyas claves son símbolos, de forma similar a como se simularon antes de que el idioma los apoyara oficialmente.

Los errores particulares que está recibiendo probablemente dependen de la implementación. Por ejemplo, al ejecutar el último fragmento de código en irb, se muestra la función que genera el TypeError:

2.1.2 :001 > def bar *; end => :bar 2.1.2 :002 > bar(**{"a" => 3}) TypeError: wrong argument type String (expected Symbol) from (irb):2:in `core#hash_merge_kwd'' from (irb):2 from /home/mkis/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'' 2.1.2 :003 >

hash_merge_kwd es una función interna, definida aquí: https://github.com/ruby/ruby/blob/d738e3e15533e0f500789faaedcef9ed9ca362b9/vm.c#L2398


Me encontré con algo como esto recientemente.

Si está en Rails y tiene un método que toma argumentos de palabras clave y tiene un hash de params fuerte que desea enviarle, puede usar symbolize_keys en el hash de params y se separará correctamente de los argumentos, sin duplicar. necesario.

Modelo

class ContactForm def initialize(name:, email:) @name = name @email = email end # Other stuff end

Controlador

class ContactController < ApplicationController def send_mail @contact_form = ContactForm.new(contact_params) if @contact_form.submit # Do stuff end end def contact_params params.require(:contact_form).permit(:name, :email).symbolize_keys end end