CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 11 Jul 2020 06:44

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 20 mensajes ]  Ir a página 1, 2  Siguiente
Autor Mensaje
NotaPublicado: 22 Feb 2006 12:08 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 22 Sep 2004 09:33
Mensajes: 1100
Hola a todos,

Ando trasteando un poco con InformATE, y me ha surgido la necesidad de pasar a una función un parámetro por referencia en vez de por valor. ¿Es posible? ¿algun código de alguien que lo haya hecho?

La idea es tener:
Código:
object objeto with
variable 1,
antes[;
tirar: suma(variable);
];


y una función de tipo:

Código:
[suma a;
a++;
];


Y que al llamar a "tirar objeto", el valor que se cambie sea el de variable...

Gracias por adelantado
Mapache


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 22 Feb 2006 12:22 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

Me temo que en inform los tipos primitivos (enteros, en el caso de la máquina z y Glulx) se pasan por valor, si bien los objetos se pasan por referencia. ¿Cómo es ésto posible?

En Inform todos los valores son números, al fin y al cabo, y esos numeros se pasan por valor. La cuestión es que cuando pasamos una cadena o un objeto, pasamos en realidad un número que es su posición en memoria, que se pasa por valor como cualquier número. Así, cuando cambiamos algo de ese objeto o cadena, los cambios son visibles también para la función que ha llamado; de hecho, para cualquier otra función.

En tu caso, todo ésto no es demasiado importante, porque fíjate, está hablando de un dato miembro de un objeto:

Código:
object objeto
with
    variable 1,
    antes[;
        tirar: suma(variable);
    ]
;


Al que puedes dotar de un nuevo método (función miembro), que haga el trabajo:

Código:
object objeto
with
    variable 1,
    antes[;
        tirar: self.incrementar();
    ],
    incrementar [;
        self.variable ++;
    ]
;


Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 22 Feb 2006 22:02 
Desconectado
Grafista
Grafista

Registrado: 09 Mar 2004 17:20
Mensajes: 504
baltasarq escribió:
En tu caso, todo ésto no es demasiado importante, porque fíjate, está hablando de un dato miembro de un objeto:


Cierto, aunque me estoy imaginando que alomejor si a Mapa le interesa tanto lo de pasar parámetros precisamente por referencia es porque pretende que distintos objetos llamen a esa función (podría ser útil sobre todo si son objetos de diferentes clases, un suponer...)

En ese caso sería interesante aplicar lo que has dicho de que los objetos sí se pasan por referencia y hacer algo como...

Código:
object objeto with
variable 1,
antes[;
tirar: suma(self);
];

[suma obj;
obj.variable ++;
];


Y así tendríamos una función "suma" que recibiría como parámetro un objeto (llamemosle "obj") y cuya actuación consistiría en aumentar la propiedad "variable" de cualquier objeto que la llamase. (Todo ello, por supuesto, suponiendo que mi imaginación de que eso es lo que le interesa hacer sea cierta XDDD )


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 08:56 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

Citar:
Cierto, aunque me estoy imaginando que alomejor si a Mapa le interesa tanto lo de pasar parámetros precisamente por referencia es porque pretende que distintos objetos llamen a esa función (podría ser útil sobre todo si son objetos de diferentes clases, un suponer...)


En ese caso sería interesante tratar de buscar una solución como tener una clase padre común donde se implemente ese método. Sin saber qués es lo que necesita Mapache, es difícil imaginárselo, pero seguro que es una funcionalidad común.

Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 10:34 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 22 Sep 2004 09:33
Mensajes: 1100
baltasarq escribió:
Hola !

Citar:
Cierto, aunque me estoy imaginando que alomejor si a Mapa le interesa tanto lo de pasar parámetros precisamente por referencia es porque pretende que distintos objetos llamen a esa función (podría ser útil sobre todo si son objetos de diferentes clases, un suponer...)


En ese caso sería interesante tratar de buscar una solución como tener una clase padre común donde se implemente ese método. Sin saber qués es lo que necesita Mapache, es difícil imaginárselo, pero seguro que es una funcionalidad común.

Salud !

Baltasar


Hola,

Como dirían en la hora chanante, efectivamente... y no.

La idea es hacer una pequeña librería, ya que mi código siempre se llena de esto (en pseudocodigo):

Código:
object algo
with flag_uno flag_on,
antes[;
Examinar:if(self.flag_uno==flag_on){
                    self.flag_uno=flag_off;
                    "lo que sea";}
               "otra respuesta";
];


lo que me gustaría es una librería que permitiera hacer algo así:

Código:
object algo
with flag_uno flag_on,
antes[;
Examinar:if(compruebaycambia(self.flag_uno,flag_on))
                    "lo que sea";
               "otra respuesta";
];


de tal forma que compruebaycambia compruebe el flag y lo cambie si es necesario... ¿mejor explicado?

Por ello (el objetivo es una librería), la solución que pasa por usar una clase con esa función definida no sería la óptima (aunque sí que es funcional, y supongo que será la solución menos mala).

Saludetes
Mapache


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 12:30 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 15 Dic 2004 21:28
Mensajes: 2302
mapache escribió:
Por ello (el objetivo es una librería), la solución que pasa por usar una clase con esa función definida no sería la óptima (aunque sí que es funcional, y supongo que será la solución menos mala).


¿Por qué no sería la óptima? Yo sí lo creo.


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 13:31 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

Citar:
Como dirían en la hora chanante, efectivamente... y no.
La idea es hacer una pequeña librería, ya que mi código siempre se llena de esto (en pseudocodigo):

Código:
object algo
with flag_uno flag_on,
antes[;
Examinar:if(self.flag_uno==flag_on){
                    self.flag_uno=flag_off;
                    "lo que sea";}
               "otra respuesta";
];



Eso es mucho más sencillo. Lo que quieres es que se visualice un mensaje en una ocasión y otro en otra.

Puedes utilizar mi librería responde:

Código:
include "responde.h"


... y después crear un objeto de respuestas:

Código:
RespondeUnaVez respondeAX
private
    mensajes
      "Lo que sea"
      "Cualquier otra cosa"
;


Finalmente, lo utilizamos en un objeto:

Código:
object algo
with
  antes[;
    Examinar:
      print (string) respondeAX.dev_msg(), "^";
      rtrue;
  ]
;



Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 13:47 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 22 Sep 2004 09:33
Mensajes: 1100
Hola Balta,

baltasarq escribió:
Hola !

Eso es mucho más sencillo. Lo que quieres es que se visualice un mensaje en una ocasión y otro en otra.

Puedes utilizar mi librería responde:

Código:
include "responde.h"


... y después crear un objeto de respuestas:

Código:
RespondeUnaVez respondeAX
private
    mensajes
      "Lo que sea"
      "Cualquier otra cosa"
;


Finalmente, lo utilizamos en un objeto:

Código:
object algo
with
  antes[;
    Examinar:
      print (string) respondeAX.dev_msg(), "^";
      rtrue;
  ]
;



Salud !

Baltasar


Conozco tu librería y es perfecta si sólo quieres visualizar mensajes. Pero supón que además quieres mover un objeto del limbo a la localidad...

Saludetes
Mapache


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 13:53 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5312
Ubicación: Coruña
Mapache escribió:
de tal forma que compruebaycambia compruebe el flag y lo cambie si es necesario... ¿mejor explicado?

Por ello (el objetivo es una librería), la solución que pasa por usar una clase con esa función definida no sería la óptima (aunque sí que es funcional, y supongo que será la solución menos mala).


Como sabéis yo no tengo ni la más remota idea de Inform, pero en programación orientada a objetos en general creo que lo lógico sería simplemente hacer una clase "wrapper" sobre el flag, que implemente la funcionalidad que quieres delegando en un atributo flag. En Java esto sería algo como

Código:
class Flag
{
  private boolean value;
  public Flag ( boolean value ) { set(value); }
  public boolean test () { return value; }
  public boolean set ( boolean value ) { this.value = value; }
  public boolean testAndSet ( boolean newvalue )
  {
     boolean retval = this.value;
     this.value = newvalue;
     return retval; 
  }
}


Y luego harías cosas como

Flag miFlag = new Flag(true);
if ( miFlag.test() ) ...
if ( miFlag.testAndSet(false) ) { mensaje1; } else { mensaje2; }

Siendo inform orientado a objetos, tiene que poderse hacer lo mismo.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 17:16 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

Citar:
Como sabéis yo no tengo ni la más remota idea de Inform, pero en programación orientada a objetos en general creo que lo lógico sería simplemente hacer una clase "wrapper" sobre el flag, que implemente la funcionalidad que quieres delegando en un atributo flag. En Java esto sería algo como


El problema es que inform es muy particular. Si vas a crear objetos, tienes que indicar primero cuántos vas a crear como máximo. Así, tu clase Flag tendría que tener un máximo:

Código:
class Flag(50)
private
    flag false,
with
    ! más cosas ...
;


Y después tendrías que utilizar create:

Código:
x = Flag.create()

if ( x ~= Nothing ) {
      ! ... meterlo donde sea ...
}


Como ves, bastante tedioso. Además, no es posible crear métodos estáticos (es decir, asociados a las clases), por lo que peor todavía.

En "El trono ...", los decorados se construyen de forma dinámica, creando los objetos necesarios según los objetos que existen de cada tipo (Bosque, CallePueblo ... etc.) ... empecé con valores altos hasta ajustarlo según lo necesario (como se puede ver en la rutina Inicializar();)

Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 23 Feb 2006 17:19 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

mapache escribió:
Conozco tu librería y es perfecta si sólo quieres visualizar mensajes. Pero supón que además quieres mover un objeto del limbo a la localidad...


No es cierto, fíjate que en responde.h tienes las declaraciones de las clases correspondientes. Verás que hay ciertos métodos que puedes sobreescribir para cada uno de los objetos que crees, y pienso que esos métodos (que se activan cuando se imprime un mensaje, o cuando se llega al final de los mensajes, como en RespondeUnaVez) serán muy útiles para tu caso.

Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto: responde.h
NotaPublicado: 24 Feb 2006 09:27 
Desconectado
Semimomio
Semimomio
Avatar de Usuario

Registrado: 23 Abr 2004 08:49
Mensajes: 2956
Ubicación: España (Galicia)
Hola !

Bueno, ahí va, que es que hay que darlo todo hecho, caray ....

Código:
class respondeUnaVez
class respondona
with
   haz_accion_final [; return; ],
   dev_msg [n;
      if (self.num == self.longitud() - 1)
            {
         self.haz_accion_final();
         return self.elemento(self.num);
      }
      else {
         n = self.num;
         self.num++;
         self.accion();
         return self.elemento(n);
      }
   ]
;


Como puedes ver, haz_accion() se ejecuta cada vez que se muestra un mensaje y no se ha llegado al final (en tu caso, serían dos mensajes). haz_accion_final() se ejecuta sólo cuando se llega al mensaje final.

Así:

Código:
RespondeUnaVez respondeGiraLlave
private
    elementos
        "El motor tose y se retuerce, impotente ..."
        "Tras una serie de gemidos y de tosidos quejumbrosos, se pone en marcha. ¡Por fin!"
with
    haz_accion [;
        garaje.incrementaGasesToxicos( 10 );
    ],
    haz_accion_final [;
        motor.estaArrancado( true );
    ]
;


Salud !

Baltasar

_________________
-- Baltasar, el arquero


Arriba
 Perfil  
 
 Asunto:
NotaPublicado: 24 Feb 2006 20:57 
Desconectado
Grafista
Grafista

Registrado: 09 Mar 2004 17:20
Mensajes: 504
En cualquier caso, ya que Inform, en principio, no pasa parámetros a las funciones por referencia sino por valor (ver http://www.firthworks.com/roger/informfaq/dd.html#8 para tener una visión de conjunto) pero se maneja con valores absolutos (usea, numeritos) para identificar los objetos... y sus respectivas propiedades, pues... que en el caso del primer ejemplo (el de la suma) también funcionaría con total tranquilidad esto otro...

Código:
object objeto
with
variable 1,
antes
[;
   tirar: suma(self, variable);
];

[Suma obj prop;
   obj.prop ++;
];


En este caso "suma" es una función que recibe como parámetro un objeto y una propiedad y aumenta esta última. No es exactamente lo que se dice "por referencia" pero es lo que más se le parece.
(Para serlo más "exactamente" en el sentido clásico del término habría que mandar a la función la dirección de memoria de la propiedad y que en ella se manipulase su contenido. Lo cierto es que ni siquiera estoy seguro de que esto se pudiera hacer en ensamblador de Z... mandar la dirección como parametro sí, pero hasta ahí llegué, y de todos modos con lo anterior debería ir sobradísimo para lo que quería Mapache )

¡Todo es cuestión de darle vueltas! :o


Arriba
 Perfil  
 
 Asunto: Re: responde.h
NotaPublicado: 25 Feb 2006 14:22 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 22 Sep 2004 09:33
Mensajes: 1100
baltasarq escribió:
Hola !
....
Bueno, ahí va, que es que hay que darlo todo hecho, caray ....
Como puedes ver, haz_accion() se ejecuta cada vez que se muestra un mensaje y no se ha llegado al final (en tu caso, serían dos mensajes). haz_accion_final() se ejecuta sólo cuando se llega al mensaje final.

Así:

Código:
RespondeUnaVez respondeGiraLlave
private
    elementos
        "El motor tose y se retuerce, impotente ..."
        "Tras una serie de gemidos y de tosidos quejumbrosos, se pone en marcha. ¡Por fin!"
with
    haz_accion [;
        garaje.incrementaGasesToxicos( 10 );
    ],
    haz_accion_final [;
        motor.estaArrancado( true );
    ]
;


Salud !

Baltasar


Hola Baltasar,

Lo primero muchas gracias por todas las molestias que te has tomado... efectivamente responde.h hace mas cosas de las que pensaba :oops:

Lo único, es que lo que buscaba era simplificar el código para tareas simples, y con el uso de responde.h me parece que se complica...

Pero vamos, que me encanta ver el alto nivel que tenéis en Inform cada vez que alguien pregunta algo. Así da gusto :)

A ver en que acaba todo esto...

Saludetes
Mapache


Arriba
 Perfil  
 
 Asunto: Re: responde.h
NotaPublicado: 25 Feb 2006 19:29 
Desconectado
Grafista
Grafista

Registrado: 09 Mar 2004 17:20
Mensajes: 504
mapache escribió:
lo que buscaba era simplificar el código para tareas simples,
A ver en que acaba todo esto...


Pues en un momento dado, aplicando lo que decía antes, una de las posibilidades podría ser hacer una rutina "compruebaycambia" del estilo de:

Código:
[compruebaycambia obj prop val_01 val_02;
   if (obj.prop==val_01)
   {
      obj.prop=val_02;
      rtrue;
   }
   rfalse;
];


...que recibe como parámetros un objeto, una propiedad suya, un valor con el que la vamos a comparar, y otro con el que la cambiaremos en caso de coincidencia. Si hay tal coincidencia retorna true y si no devuelve false. Así podría ser llamada desde un objeto de un modo como este:

Código:
Object algo
with
flag_uno flag_on,
antes
[;
   Examinar:
      if(compruebaycambia(self,flag_uno,flag_on,flag_off))
      "Mensaje 1";
      "Mensaje 2";
]
;


Estoy asumiendo que flag_on y flag_off (posibles valores de la propiedad flag_uno) están convenientemente definidos en alguna otra parte del programa (ya sea como constantes, variables globales, o lo que fuera)
En el hipotético caso de que estos flag_on y flag_off fueran a valer siempre 1 o 0 el código se puede optimizar un poco más para ahorrar un poco de espacio y ganar algo de legibilidad, que siempre viene bien.

Código:
Object algo
with
flag_uno true,
antes
[;
   Examinar:
      if(compruebaycambia(self,flag_uno))
      "Mensaje 1";
      "Mensaje 2";
];

[compruebaycambia obj prop;
   if (obj.prop) obj.prop=false; else rfalse;
];


Notese que el truco está en que si mando como parámetro el valor de la propiedad ("self.flag_uno") estoy condenado a hacerlo siempre "por valor" y no puedo hacer referencia de ningún tipo en la función a la que estoy llamando... pero lo que sí puedes hacer es mandar como parámetros los identificadores del objeto por un lado (self) y de la propiedad por otro (flag_uno), que para Inform son números internos determinados en tiempo de compilación y que funcionan como valores, y una vez en la función "reconstruir" la referencia (que es lo que hago al juntar obj y prop en "obj.prop") de tal suerte que apunta al lugar correcto.


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 20 mensajes ]  Ir a página 1, 2  Siguiente

Todos los horarios son UTC + 1 hora


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Saltar a:  
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM