Duda de sintaxis - nombre de campo variable

A la hora de sacar un campo en una vista, para leer los campos
count_subtipo1, count_subtipo2, etc, puedo “componer” el nombre del
campo mediante:
eval(“autor.count_subtipo#{@tema.subtipo_id}”)

Y eso me devuelve, para un tema del subtipo 7, el contenido del campo
count_subtipo7 de ese autor, que es justo lo que quería.

Pero esto que funciona para leer los campos, no funciona en el
controlador para escribir:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

-> SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

s2

Fernando C. wrote:

A la hora de sacar un campo en una vista, para leer los campos
count_subtipo1, count_subtipo2, etc, puedo “componer” el nombre del
campo mediante:
eval(“autor.count_subtipo#{@tema.subtipo_id}”)

Y eso me devuelve, para un tema del subtipo 7, el contenido del campo
count_subtipo7 de ese autor, que es justo lo que quería.

Pero esto que funciona para leer los campos, no funciona en el
controlador para escribir:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

-> SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

s2

Hmm, se me ocurre usar attr_accessor

class Yo
attr_accessor “count_subtipo_#{contador}”
end

o algo por el estilo.

Fernando C. escribió:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

→ SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

Prueba esto:

eval(“@yo.count_subtipo#{@tema.subtipo_id} += 1”)

Si no tienes mucha práctica ten mucho cuidado con lo que le puede llegar
a eval, ya sabes lo que dicen con estas cosas: “un gran poder conlleva
una gran responsabilidad” :wink:


Raul M. - Freelance Web D.
http://raul.murciano.net

Fernando C. escribió:

A la hora de sacar un campo en una vista, para leer los campos
count_subtipo1, count_subtipo2, etc, puedo “componer” el nombre del
campo mediante:
eval(“autor.count_subtipo#{@tema.subtipo_id}”)

No seria mejor hacer algo como
autor.send(“count_subtipo#{tema.subtipo_id}”)

Y eso me devuelve, para un tema del subtipo 7, el contenido del campo
count_subtipo7 de ese autor, que es justo lo que quería.

Pero esto que funciona para leer los campos, no funciona en el
controlador para escribir:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

Y esto a lo mejor con
value = @yo.send(“count_subtipo#{@tema.subtipo_id}”)

@yo.send(“count_subtipo#{@tema.subtipo_id}=”,value+1)

-> SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

s2

Pero tampoco me hagas mucho caso.
Un saludo y suerte.

cartuchoGL wrote:

Fernando C. escribió:

A la hora de sacar un campo en una vista, para leer los campos
count_subtipo1, count_subtipo2, etc, puedo “componer” el nombre del
campo mediante:
eval(“autor.count_subtipo#{@tema.subtipo_id}”)

No seria mejor hacer algo como
autor.send(“count_subtipo#{tema.subtipo_id}”)

eval(“autor.count_subtipo#{@tema.subtipo_id}”) funciona… ¿que ventaja
tiene hacerlo con send? Es que no sé cómo funciona el send…

Y eso me devuelve, para un tema del subtipo 7, el contenido del campo
count_subtipo7 de ese autor, que es justo lo que quería.

Pero esto que funciona para leer los campos, no funciona en el
controlador para escribir:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

Y esto a lo mejor con
value = @yo.send(“count_subtipo#{@tema.subtipo_id}”)

@yo.send(“count_subtipo#{@tema.subtipo_id}=”,value+1)

Perfecto!! esto es lo que buscaba. Muchas gracias!!

Edgar J. Suarez wrote:

Fernando C. wrote:

A la hora de sacar un campo en una vista, para leer los campos
count_subtipo1, count_subtipo2, etc, puedo “componer” el nombre del
campo mediante:
eval(“autor.count_subtipo#{@tema.subtipo_id}”)

Y eso me devuelve, para un tema del subtipo 7, el contenido del campo
count_subtipo7 de ese autor, que es justo lo que quería.

Pero esto que funciona para leer los campos, no funciona en el
controlador para escribir:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

-> SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

s2

Hmm, se me ocurre usar attr_accessor

class Yo
attr_accessor “count_subtipo_#{contador}”
end

o algo por el estilo.

No le veo mucho sentido a emplear attr_accessor… los attr_accessor son
campos “virtuales” (hasta donde yo sé), y mis count_subtipoxx son campos
que realmente existen. Salvo que con attr_accessor se puedan hacer cosas
que yo no sé, que podría ser…

s2

Fernando C. escribió:

Y ahora, la duda: si esto funciona, y el send de cartuchoGL también
funciona, ¿alguien sabría decir qué es mejor?

A mí me parece mejor el send de cartuchoGL, normalmente sólo recurro a
eval cuando no encuentro otro remedio.


Raul M. - Freelance Web D.
http://raul.murciano.net

Raul M. wrote:

Fernando C. escribió:

    eval("@yo.count_subtipo#{@tema.subtipo_id}") += 1
    @yo.eval("count_subtipo#{@tema.subtipo_id}") += 1

→ SyntaxError

¿Sabéis cual es la sintaxis para lo que quiero hacer?

Prueba esto:

eval(“@yo.count_subtipo#{@tema.subtipo_id} += 1”)

Si no tienes mucha práctica ten mucho cuidado con lo que le puede llegar
a eval, ya sabes lo que dicen con estas cosas: “un gran poder conlleva
una gran responsabilidad” :wink:


Raul M. - Freelance Web D.
http://raul.murciano.net

También funciona!!

En principio, no es peligroso; el subtipo_id lo maneja el sistema, no
los usuarios, y además es numérico y no de texto, por lo que por ahí no
hay posibilidad de ataques… pero en todo caso, no está de más el
aviso, por si yo o alguien pensamos en utilizarlo en entornos menos
seguros.

Y ahora, la duda: si esto funciona, y el send de cartuchoGL también
funciona, ¿alguien sabría decir qué es mejor?

s2 y gracias!!

Fernando C. escribió:

Raul M. - Freelance Web D.

Y ahora, la duda: si esto funciona, y el send de cartuchoGL también
funciona, ¿alguien sabría decir qué es mejor?

s2 y gracias!!

Bueno, la diferencia es grande, los dos hacen cosas distintas, con eval
lo que haces es llamar al interpretre de ruby para ejecutar ese codigo,
puedes hacer lo que quieras en eval.

eval(‘2+2’)
devolveria 4 y
eval(‘2+2;2+1’)
devolveria 3, por el rollo ese de devolver lo ultimo ejecutado. Incluso
algo como:

eval(<<-COSA)
class Pepito
def hola
puts ‘hola’
end
end
COSA

Puedes ver eval como una especie de interprete de ruby dentro de ruby.

En cambio send es un metodo de la clase Object que lo que hace es,
hablando en terminos orientados a objetos, mandar un mensaje al objeto,
por ejemplo siguiendo el eval anterior podriamos:

a=Pepito.new
a.hola
a.send(‘hola’)

El efecto de las dos ultimas expresiones es exactamente el mismo, llamar
al metodo hola.

Y para no enrollarme mas y responder a tu pregunta de cual es mejor, la
respuesta es ‘rendimiento’, y para muetra un boton:(basado en el codigo
del Programing Ruby 2ªEd pag409)

require ‘benchmark’
include Benchmark

test = ‘soy una cadena’
n = 100000
bm(12) {|x|
x.report(‘send’) { n.times { test.send(:length) } }
x.report(‘eval’) { n.times { eval ‘test.length’ } }
}

que en mi maquina devuelve:

              user     system      total        real

send 0.040000 0.000000 0.040000 ( 0.041161)
eval 0.380000 0.000000 0.380000 ( 0.382172)

Conclusion eval es unas 9 veces mas lento que usar send.

Un saludo.

cartuchoGL wrote:

Fernando C. escribió:

Y ahora, la duda: si esto funciona, y el send de cartuchoGL también
funciona, ¿alguien sabría decir qué es mejor?

Bueno, la diferencia es grande, los dos hacen cosas distintas, con eval lo que haces es llamar al interpretre de ruby para ejecutar ese codigo, puedes hacer lo que quieras en eval.

eval(‘2+2’)
devolveria 4 y
eval(‘2+2;2+1’)
devolveria 3, por el rollo ese de devolver lo ultimo ejecutado. Incluso algo como:

eval(<<-COSA)
class Pepito
def hola
puts ‘hola’
end
end
COSA

Puedes ver eval como una especie de interprete de ruby dentro de ruby.

En cambio send es un metodo de la clase Object que lo que hace es, hablando en terminos orientados a objetos, mandar un mensaje al objeto, por ejemplo siguiendo el eval anterior podriamos:

a=Pepito.new
a.hola
a.send(‘hola’)

El efecto de las dos ultimas expresiones es exactamente el mismo, llamar al metodo hola.

Y para no enrollarme mas y responder a tu pregunta de cual es mejor, la respuesta es ‘rendimiento’, y para muetra un boton:(basado en el codigo del Programing Ruby 2ªEd pag409)

require ‘benchmark’
include Benchmark

test = ‘soy una cadena’
n = 100000
bm(12) {|x|
x.report(‘send’) { n.times { test.send(:length) } }
x.report(‘eval’) { n.times { eval ‘test.length’ } }
}

que en mi maquina devuelve:

              user     system      total        real

send 0.040000 0.000000 0.040000 ( 0.041161)
eval 0.380000 0.000000 0.380000 ( 0.382172)

Conclusion eval es unas 9 veces mas lento que usar send.

Muchísimas gracias, cartuchoGL; no sólo has respondido perfectamente la
pregunta, sino que nos has dado una lección que seguramente muchos
aprovecharemos!!

s2