No puedo ver variable de clase

Hola a todos,

Estoy empezando con Ruby y con Rails y como vengo del mundo Java igual
estoy haciendo algo mal. Dentro de Rails he creado una clase que se
llama Documento y que he guardado en /lib. Desde el controlador creo una
instancia de esa clase (fuera de todos los metodos) y desde uno de los
métodos puedo asignarle a los atributos propiedades. La cuestión es que
cuando intento acceder a esos atributos desde otro método de la misma
clase parece que hago algo mal pq no me los coge. Os pego el codigo. A
ver si alguien me puede hechar un cable. He buscado por google pero no
encuentro un ejemplo claro de lo que quiero hacer (que es simplemente
tener un objeto instanciado dentro del controlador para poder acceder a
los datos que almacene desde cualquier metodo del mismo controlador.
Gracias

class MotorRecursoController < ApplicationController

@@recurso = Documento.new

def dispara_recurso

end

def preview_recurso
@parametro = params[:recurso]
end

def chequea_datos
#@nombre=params[:contact][:name]
#@recurso = Documento.new
@@recurso.nombre=params[:contact][:name]
@datos = @@recurso.nombre
end

def micropago
@datos = @@recurso.nombre
end

end

On Aug 11, 2007, at 11:11 PM, Chris Palau wrote:

Estoy empezando con Ruby y con Rails y como vengo del mundo Java igual
estoy haciendo algo mal. Dentro de Rails he creado una clase que se
llama Documento y que he guardado en /lib. Desde el controlador
creo una
instancia de esa clase (fuera de todos los metodos) y desde uno de los
métodos puedo asignarle a los atributos propiedades. La cuestión es
que
cuando intento acceder a esos atributos desde otro método de la misma
clase parece que hago algo mal pq no me los coge.

Quieres decir que los cambis no se comparten con otro metodo llamando
a este en una segunda peticion web? Si es asi seguramente estes
desarrollando en modo “development”, en cuyo caso la clase del
controlador se borra y se vuelve a cargar en cada peticion, por lo
que nada a nivel de clase persiste entre peticiones.

Os pego el codigo. A
ver si alguien me puede hechar un cable. He buscado por google pero no
encuentro un ejemplo claro de lo que quiero hacer (que es simplemente
tener un objeto instanciado dentro del controlador para poder
acceder a
los datos que almacene desde cualquier metodo del mismo controlador.

La programacion web en Java es multithread, la programacion web en
Rails es multiproceso (hoy por hoy incluso con JRuby, donde hay un
broker en el contenedor de servlets que instancia varios interpretes
Ruby separados.)

Una consecuencia de esto es que, para una clase C, hay “tantas Cs” en
una aplicacion como procesos, porque en cada proceso corre una
maquina virtual distinta. Por ello, los cambios en una variable de
clase en un controlador C no se reflejan en la en el resto de
maquinas virtuales. Es por este motivo que la instancias a nivel de
clase suelen reservarse para cosas de caracter constante, por ejemplo
cachear una tabla de paises. De otro modo has de establecer un
mecanismo externo de sincronizacion entre los procesos (e.g., la base
de datos).

Eso es algo que hay que tener claro al pasar de Java a Ruby (y otros
muchos frameworks).

Ayuda? Si sigues sin ver como implementar aquello por favor escribe
de nuevo con algun detalle mas, que significa, cuando se actualiza,
si depende del usuario, …

– fxn

Xavier N. wrote:

On Aug 11, 2007, at 11:11 PM, Chris Palau wrote:

Estoy empezando con Ruby y con Rails y como vengo del mundo Java igual
estoy haciendo algo mal. Dentro de Rails he creado una clase que se
llama Documento y que he guardado en /lib. Desde el controlador
creo una
instancia de esa clase (fuera de todos los metodos) y desde uno de los
m�todos puedo asignarle a los atributos propiedades. La cuesti�n es
que
cuando intento acceder a esos atributos desde otro m�todo de la misma
clase parece que hago algo mal pq no me los coge.

Quieres decir que los cambis no se comparten con otro metodo llamando
a este en una segunda peticion web? Si es asi seguramente estes
desarrollando en modo “development”, en cuyo caso la clase del
controlador se borra y se vuelve a cargar en cada peticion, por lo
que nada a nivel de clase persiste entre peticiones.

Os pego el codigo. A
ver si alguien me puede hechar un cable. He buscado por google pero no
encuentro un ejemplo claro de lo que quiero hacer (que es simplemente
tener un objeto instanciado dentro del controlador para poder
acceder a
los datos que almacene desde cualquier metodo del mismo controlador.

La programacion web en Java es multithread, la programacion web en
Rails es multiproceso (hoy por hoy incluso con JRuby, donde hay un
broker en el contenedor de servlets que instancia varios interpretes
Ruby separados.)

Una consecuencia de esto es que, para una clase C, hay “tantas Cs” en
una aplicacion como procesos, porque en cada proceso corre una
maquina virtual distinta. Por ello, los cambios en una variable de
clase en un controlador C no se reflejan en la en el resto de
maquinas virtuales. Es por este motivo que la instancias a nivel de
clase suelen reservarse para cosas de caracter constante, por ejemplo
cachear una tabla de paises. De otro modo has de establecer un
mecanismo externo de sincronizacion entre los procesos (e.g., la base
de datos).

Eso es algo que hay que tener claro al pasar de Java a Ruby (y otros
muchos frameworks).

Ayuda? Si sigues sin ver como implementar aquello por favor escribe
de nuevo con algun detalle mas, que significa, cuando se actualiza,
si depende del usuario, …

– fxn

Gracias por tu respuesta Xavier.
Quiza me explique mal. Te resumo lo que quiero hacer.

  1. Tengo un controlador A que llama a la vista A que tiene un formulario
  2. el usuario rellena unos datos de ese formulario.
  3. Tengo una clase propia mia (escrita en ruby) que en uno de los
    métodos del controlador se instancia (@clase = Documento.new) y que
    guarda en cada atributo lo que me han pasado por el formulario.

(Hasta ahí todo bien, pero cuando intento acceder desde otro método de
ese controlador a @clase.atributo, no me imprime nada) Es decir yo
declaro esa clase mia de ambito general de la clase y por ejemplo en
Java tengo acceso a esos atributos desde cualquier parte de la clase. En
este caso al intentar acceder a los atributos desde otro método de la
clase no me imprime nada y como tampoco se como depurarlo no se que
pasa…

Gracias por tu ayuda.

Chris

Raul M. wrote:

Hola Chris,

Chris Palau escribió:

  1. Tengo un controlador A que llama a la vista A que tiene un
    formulario
  2. el usuario rellena unos datos de ese formulario.
  3. Tengo una clase propia mia (escrita en ruby) que en uno de los
    métodos del controlador se instancia (@clase = Documento.new) y que
    guarda en cada atributo lo que me han pasado por el formulario.

(Hasta ahí todo bien, pero cuando intento acceder desde otro método de
ese controlador a @clase.atributo, no me imprime nada) Es decir yo
declaro esa clase mia de ambito general de la clase y por ejemplo en
Java tengo acceso a esos atributos desde cualquier parte de la clase.

¿Todo esto ocurre en la misma petición? ¿Podrías enviar los métodos del
controlador en los que ocurre todo esto?

Hola,

Te pego el controlador. Como puedes ver en chequea_datos le asigno un
atributo que me viene de un parametro del formulario. Hasta ahi bien.
Luego en el método micropago asigno el atributo de ese objeto que he
creado (@datos=@@recurso.nombre), pero nada de nada no me rellena nada.
Sin embargo en chequea_datos si funciona. Lo he probado también con
variables locales pero tampoco funciona. Por lo visto la asignación de
ese atributo se queda sólo en el método chequea_datos y no para el resto
de métodos del controlado.Por lo que he podido investigar por ahi creo
que hay algo que estoy haciendo mal a la hora de crear el objeto
Documento.new y que tenga ambito para todo el controlador. Gracias

class MotorRecursoController < ApplicationController

@@recurso = Documento.new

def dispara_recurso

end

def preview_recurso
@parametro = params[:recurso]
end

def chequea_datos
@@recurso.nombre=params[:contact][:name]
@datos = @@recurso.nombre
end

def micropago
@datos = @@recurso.nombre
end

end

On Aug 12, 2007, at 10:10 AM, Chris Palau wrote:

(Hasta ahí todo bien, pero cuando intento acceder desde otro método de
ese controlador a @clase.atributo, no me imprime nada) Es decir yo
declaro esa clase mia de ambito general de la clase y por ejemplo en
Java tengo acceso a esos atributos desde cualquier parte de la
clase. En
este caso al intentar acceder a los atributos desde otro método de la
clase no me imprime nada y como tampoco se como depurarlo no se que
pasa…

La clave aqui es si hay una peticion entre el seteo y la lectura.

(a) Si la hay aplica lo que explique sobre el modo “development”.
Salvo que estes en mono-proceso y en produccion simplemente no
funcionara, habria que escribir otra cosa.

(b) Si no la hay entonces tienes un bug (ver demo abajo). En este
caso podria pasar ademas que en realidad no necesites una variable de
clase, ya que la manera normal de compartir estado entre llamadas a
metodos de un mismo objeto son las variables de instancia.

– fxn

fxn@feynman:~/tmp$ cat foo.rb
class Foo
@@x = 0
def incx
@@x += 1
end
def debugx
@@x
end
end

f, g = Foo.new, Foo.new

puts f.incx
puts f.debugx
puts g.incx
puts f.debugx
puts g.debugx
fxn@feynman:~/tmp$ ruby foo.rb
1
1
2
2
2

Xavier N. wrote:

On Aug 12, 2007, at 10:10 AM, Chris Palau wrote:

(Hasta ah� todo bien, pero cuando intento acceder desde otro m�todo de
ese controlador a @clase.atributo, no me imprime nada) Es decir yo
declaro esa clase mia de ambito general de la clase y por ejemplo en
Java tengo acceso a esos atributos desde cualquier parte de la
clase. En
este caso al intentar acceder a los atributos desde otro m�todo de la
clase no me imprime nada y como tampoco se como depurarlo no se que
pasa…

La clave aqui es si hay una peticion entre el seteo y la lectura.

(a) Si la hay aplica lo que explique sobre el modo “development”.
Salvo que estes en mono-proceso y en produccion simplemente no
funcionara, habria que escribir otra cosa.

(b) Si no la hay entonces tienes un bug (ver demo abajo). En este
caso podria pasar ademas que en realidad no necesites una variable de
clase, ya que la manera normal de compartir estado entre llamadas a
metodos de un mismo objeto son las variables de instancia.

– fxn

fxn@feynman:~/tmp$ cat foo.rb
class Foo
@@x = 0
def incx
@@x += 1
end
def debugx
@@x
end
end

f, g = Foo.new, Foo.new

puts f.incx
puts f.debugx
puts g.incx
puts f.debugx
puts g.debugx
fxn@feynman:~/tmp$ ruby foo.rb
1
1
2
2
2

Gracias Xavier,

Esta es la pequeña clase con la que intento trabajar:

class Documento
attr_accessor :nombre, :apellidos
end

Despues en el controlador tengo estos métodos:

def chequea_datos
@@recurso.nombre=params[:contact][:name]
@datos = @@recurso.nombre
end

def micropago
@datos = @@recurso.nombre
end

Independientemente si es variable de clase o variable de instancia en
ambos métodos ¿@datos deberia contener la misma info no ? El proceso es
primero se llama a chequea_datos y luego desde la vista de chequea_datos
llamo al action micropago, pero la vista de micropago ya no muestra
nada al intentar mostrar @datos.

Chris

On Aug 12, 2007, at 12:11 PM, Chris Palau wrote:

@datos = @@recurso.nombre
chequea_datos
llamo al action micropago, pero la vista de micropago ya no muestra
nada al intentar mostrar @datos.

Me parece que no comprendes la opcion (a)

(a) Si la hay aplica lo que explique sobre el modo “development”.
Salvo que estes en mono-proceso y en produccion simplemente no
funcionara, habria que escribir otra cosa.

Entendiste lo del borrado de clases etc. en mi primer mail?

– fxn

Hola Chris,

Chris Palau escribió:

  1. Tengo un controlador A que llama a la vista A que tiene un
    formulario
  2. el usuario rellena unos datos de ese formulario.
  3. Tengo una clase propia mia (escrita en ruby) que en uno de los
    métodos del controlador se instancia (@clase = Documento.new) y que
    guarda en cada atributo lo que me han pasado por el formulario.

(Hasta ahí todo bien, pero cuando intento acceder desde otro método de
ese controlador a @clase.atributo, no me imprime nada) Es decir yo
declaro esa clase mia de ambito general de la clase y por ejemplo en
Java tengo acceso a esos atributos desde cualquier parte de la clase.

¿Todo esto ocurre en la misma petición? ¿Podrías enviar los métodos del
controlador en los que ocurre todo esto?

Hola Chris,

Chris Palau escribió:

Te pego el controlador. Como puedes ver en chequea_datos le asigno un
atributo que me viene de un parametro del formulario. Hasta ahi bien.

Ajá, la ejecución de chequea_datos la activa el usuario cuando envía una
petición desde su navegador. Pero ¿quién activa el método micropago?
Dices que “la llamas desde la vista de chequea_datos”, imagino que te
refieres a que para activar micropago el cliente hace una nueva
petición
¿verdad?

Las variables de instancia no se conservan desde la petición anterior
(ya no tendrás nada en @datos) y si estás trabajando en modo desarrollo
tampoco tus variables de clase (@@recurso) tampoco, porque la clase se
recarga en cada nueva petición.

Resumiendo: si quieres conservar datos de una petición a otra tendrás
que guardarlos en la sesión, en base de datos o similar.

Saludos,
Raul M.

Raul M. wrote:

Hola Chris,

Chris Palau escribió:

Te pego el controlador. Como puedes ver en chequea_datos le asigno un
atributo que me viene de un parametro del formulario. Hasta ahi bien.

Ajá, la ejecución de chequea_datos la activa el usuario cuando envía una
petición desde su navegador. Pero ¿quién activa el método micropago?
Dices que “la llamas desde la vista de chequea_datos”, imagino que te
refieres a que para activar micropago el cliente hace una nueva
petición
¿verdad?

Las variables de instancia no se conservan desde la petición anterior
(ya no tendrás nada en @datos) y si estás trabajando en modo desarrollo
tampoco tus variables de clase (@@recurso) tampoco, porque la clase se
recarga en cada nueva petición.

Resumiendo: si quieres conservar datos de una petición a otra tendrás
que guardarlos en la sesión, en base de datos o similar.

Saludos,
Raul M.

Gracias Xavier y Raúl. Ya comprendí como funciona, con lo que si quiero
guardar info entre peticiones tengo que hacerlo a través de sesiones o
bd. Igual que Java. Solo pensaba que Ruby al ser un lenguage
interpretado tenia algun mecanismo para esto. Sabiendo que funciona así
perfecto. Una última pregunta para los dos. ¿Aparte de este foro existe
algun chat o foro sobre ruby on rails en español ?

Gracias.

Chris