Digamos que tengo un XML :: Element ... Quiero hacer algo como:Ruby: ¿Cómo evaluar múltiples métodos por comando de envío?
my_xml_element.send ("parent.next_sibling.next_sibling")
Digamos que tengo un XML :: Element ... Quiero hacer algo como:Ruby: ¿Cómo evaluar múltiples métodos por comando de envío?
my_xml_element.send ("parent.next_sibling.next_sibling")
En su caso es mejor utilizar instance_eval
"Test".instance_eval{chop!.chop!} #=> "Te"
Y para su código:
my_xml_element.instance_eval{parent.next_sibling.next_sibling}
uh, eso no es realmente lo que estaba pidiendo si estoy entendiendo su pregunta corr ectly. Quiero decir que enviar toma una cadena o un símbolo como una arg, y tu solución no. No creo que haya un método integrado que haga lo que quieras, pero aumenté un método que lo hará, con una prueba.
require 'test/unit'
class Example
def multi_send(str)
str.split('.').inject(self){|klass, method| klass.send(method) }
end
end
class MyTest < Test::Unit::TestCase
def test_multi_send
a = Example.new
methods = "class.to_s.downcase.chop!"
assert a.multi_send(methods) == 'exampl'
end
end
Creo que la cuestión es que usted tiene específicamente una serie de métodos definidos como una cadena, y que desea invocar que en algún objeto, ¿verdad?
class Object
def call_method_chain(method_chain)
return self if method_chain.empty?
method_chain.split('.').inject(self){|o,m| o.send(m.intern)}
end
end
>> User.first.profile.address.state.name
=> "Virginia"
>> User.first.call_method_chain("profile.address.state.name")
=> "Virginia"
En realidad, Khelll era casi correcto. Utilice esta:
methods_chain = "parent.next_sibling.next_sibling"
result = my_xml_element.instance_eval(eval methods_chain)
Este código es hasta 20 veces más rápido que el uso de split() y le permite pasar los métodos de cadena con argumentos, así:
methods = "power!(2).div(57).+(12).to_f"
42.instance_eval { eval methods }
Esto es algo poderoso. Gracias. –
El problema con la respuesta de Alfuken basada en eval es
a) eval es bastante insegura aunque rápida
B) si tiene un punto adicional (consecutivos) para la invocación de método como este
"example".instance_eval{eval "chop!..chop!"}.class
=> "examp".."examp"
"example".instance_eval {eval "chop!..chop!"}.class
=> Range # this is not what is desired
Entonces, ¿qué intenta mostrar aquí, el espacio extra entre 'instance_val' y' {'bracket? Estoy confundido. –
Lo sentimos, esto no funcionará realmente fuera del contexto de Rails ya que Object # try no está definido. – jsharpe
Editar: Funciona sin carriles ahora. – jsharpe
¿Por qué nunca había pensado en '.inject (self)' antes ??? ¡gracias! –