Hola,
> Podria estar pasando en algun lugar donde desde el debug no se puede ver
???.
Si, es una operación que debe ser atomica (con las
interrupciones deshabilitadas; incluido debugger :)
Intentá usar los senders hasta llegar a dónde se cambia el methoddict...
Ale.
----- Original Message -----
From: "kikote gregoris" <kikogregoris@...>
To: <smalltalking@...>
Sent: Wednesday, November 08, 2006 3:17 PM
Subject: Re: [objetos] RE:Cambio de instancia
> Hola Ale, Carlos
>
> Bueno, no se en que momento se hace la restauración del
MethodDictionary, pues despues de que se dispare el #doesNotUnderstand,
directamente se le envía el #transform:with: con la instancia obsoleta ya en
condiciones de responder mensajes.
> Podria estar pasando en algun lugar donde desde el debug no se puede ver
???.
>
> saludos kiko
>
> "Alejandro F. Reimondo" <aleReimondo@...> escribió:
> Hola kiko,
>
> Segun entiendo (sin ver la implementacion) la instancia obsoleta
> no entiende ningún mensaje.
> Al ser impactada por un mensaje, lo primero que debería ocurrir
> es restaurar el methodDictionary original (para que se le puedan
> enviar mensajes), luego se la debería copiar a una nueva instancia
> (aquí la instancia obsoleta ya hereda metodos de instancia de
> Object nuevamente) usando mensajes muy básicos; y por último
> se haría el bendito #become: ; todo esto en una operación "atómica".
>
> Creo que tu confusión viene porque pensas que el methodDictionary
> se setea una sola vez... y estas olvidando que ante el primer impacto
> de un mensaje se puede restaurar al valor anterior y usar el objeto
> viejo tal cual como estaba antes de iniciar la mutación.
>
> El usar el inspector, es algo complicado en estos casos;
> y es insuficiente para entender que esta pasando abajo...
>
> hasta pronto,
> Ale.
>
>
> ----- Original Message -----
> From: "kikote gregoris" <kikogregoris@...>
> To: <smalltalking@...>
> Sent: Tuesday, November 07, 2006 9:56 AM
> Subject: [objetos] RE:Cambio de instancia
>
>
> > Hola Gente
> >
> > Siguiendo con mis intentos por encontrar una solución a la mutación de
> las instancias, me surge una pregunta que no me había echo anteriormente.
> > Cundo se dispara el proceso de mutación ocurre algo que no había
notado
> y que no entiendo.
> >
> > Si detengo la ejecución en el siguiente método:
> >
> > transferNamedStateFrom: oldInstance to: newInstance
> > "Copy values of named instances variables from the old
> instance to the new instance"
> > "This implementation preserves the values of any old
> instances variables that still exist in the new instance, even if their
> relative positions have changed"
> >
> > | targetPositions targetNames newPosition |
> > "build a dictionary that maps instance variable names to
> offsets in new instance"
> > targetNames := self targetClass allInstVarNames.
> > targetPositions := Dictionary new: targetNames size.
> > targetNames inject: 1 into: [:position :name|
> > targetPositions at: name put: position.
> > position + 1].
> >
> > "Copy the value of each instance variable in the old
> instances for which
> > an identically named instance variable exists in the new
> instance."
> > self oldVariableNames inject: 1 into: [:position :name|
> > newPosition := targetPositions at: name
> ifAbsent: [0].
> > newPosition ~= 0
> > ifTrue: [newInstance instVarAt:
> newPosition put: (oldInstance instVarAt: position)].
> > position + 1].
> >
> > Se puede ver claramente que se le esta enviando un mensaje a la vieja
> instancia que se llama anObsoletXXX.
> > Esto se supone no es posible pues el comportamiento fue modificado
para
> que no entienda mas que el #doesNotUnderstand:aMessage.
> > Lo cual es cierto si abro un inspector sobre dicha instancia y trato
de
> enviarle un mensaje.
> > Como es posible que dentro de la ejecución si entienda #instVarAt: y
> sobre un inspector no ¿?.
> >
> >
> > No se si es algo natural lo que ocurra, pues en ciertos momentos me
> ocurre que olvido conceptos básicos de la TO.
> >
> >
> > Saludos kiko
> >
> > __________________________________________________
> > Correo Yahoo!
> > Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> > ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
>
>
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Bueno, no se en que momento se hace la restauración del MethodDictionary, pues despues de que se dispare el #doesNotUnderstand, directamente se le envía el #transform:with: con la instancia obsoleta ya en condiciones de responder mensajes.
Podria estar pasando en algun lugar donde desde el debug no se puede ver ???.
saludos kiko
"Alejandro F. Reimondo" <aleReimondo@...> escribió:
Hola kiko,
Segun entiendo (sin ver la implementacion) la instancia obsoleta no entiende ningún mensaje. Al ser impactada por un mensaje, lo primero que debería ocurrir es restaurar el methodDictionary original (para que se le puedan enviar mensajes), luego se la debería copiar a una nueva instancia (aquí la instancia obsoleta ya hereda
metodos de instancia de Object nuevamente) usando mensajes muy básicos; y por último se haría el bendito #become: ; todo esto en una operación "atómica".
Creo que tu confusión viene porque pensas que el methodDictionary se setea una sola vez... y estas olvidando que ante el primer impacto de un mensaje se puede restaurar al valor anterior y usar el objeto viejo tal cual como estaba antes de iniciar la mutación.
El usar el inspector, es algo complicado en estos casos; y es insuficiente para entender que esta pasando abajo...
hasta pronto, Ale.
----- Original Message ----- From: "kikote gregoris" <kikogregoris@...> To: <smalltalking@...> Sent: Tuesday, November 07, 2006 9:56 AM Subject: [objetos] RE:Cambio de instancia
> Hola Gente > > Siguiendo con mis intentos por encontrar una solución a la mutación de las instancias, me surge una
pregunta que no me había echo anteriormente. > Cundo se dispara el proceso de mutación ocurre algo que no había notado y que no entiendo. > > Si detengo la ejecución en el siguiente método: > > transferNamedStateFrom: oldInstance to: newInstance > "Copy values of named instances variables from the old instance to the new instance" > "This implementation preserves the values of any old instances variables that still exist in the new instance, even if their relative positions have changed" > > | targetPositions targetNames newPosition
| > "build a dictionary that maps instance variable names to offsets in new instance" > targetNames := self targetClass allInstVarNames. > targetPositions := Dictionary new: targetNames size. > targetNames inject: 1 into: [:position :name| > targetPositions at: name put: position. > position +
1]. > > "Copy the value of each instance variable in the old instances for which > an identically named instance variable exists in the new instance." > self oldVariableNames inject: 1 into: [:position :name| > newPosition := targetPositions at: name ifAbsent: [0]. > newPosition ~=
0 > ifTrue: [newInstance instVarAt: newPosition put: (oldInstance instVarAt: position)]. > position + 1]. > > Se puede ver claramente que se le esta enviando un mensaje a la vieja instancia que se llama anObsoletXXX. > Esto se supone no es posible pues el comportamiento fue modificado para que no entienda mas que el #doesNotUnderstand:aMessage. > Lo cual es cierto si abro un inspector sobre dicha instancia y trato de enviarle un mensaje. > Como es posible que dentro de la ejecución si entienda
#instVarAt: y sobre un inspector no ¿?. > > > No se si es algo natural lo que ocurra, pues en ciertos momentos me ocurre que olvido conceptos básicos de la TO. > > > Saludos kiko > > __________________________________________________ > Correo Yahoo! > Espacio para todos tus mensajes, antivirus y antispam ¡gratis! > ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
__________________________________________________ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Hola,
> Que devuelve los siguientes mensajes:
> #, #@ #add: #asParameter #at: #at:put:
> #class #do: #handle #height
> #invalidArgument #isNil #new
> #new: #nextPut: #notNil #size
> #value #value: #value:value: #x #y
Me quedé pensando en esta (larga?) lista
de mensajes...
Esta lista tiene los mensajes que el compilador
intentará codificar sin un envío de mensaje (por
medio de código directo).
Esto implica una operación mas rápida, pero
no implica que estos mensajes NUNCA se
envíen (no dijimos eso, pero creo que es
importante dar detalles).
El compilador, por ejemplo, optimizará
el mensaje #@ para no activar unos
métodos (y contexto, etc.) para la creación
del Point y seteo de x e y... pero lo hace
si encuentra que el receptor es un número
en otro caso SI codifica el envío.
En la mayoría de los mensajes de arriba,
el compilador es sensible a lo que está
compilando para generar los bytecodes.
Además hay que agregar a esos mensajes
aquellos que el compilador reconoce fácilmente
como #ifTrue: #ifTrue:ifFalse: #ifFalse:
#ifFalse:ifTrue: #to:by:do: #to:do: #whileTrue:
#whileFalse: #and: #or: ....
hasta pronto,
Ale.
On 7 Nov 2006 at 13:38, Alejandro F. Reimondo wrote:
> Creo que los mensajes que se cortocicuitan
> en VS pueden verse con la expresion:
>
> CompiledMethod specialSelectors keys
>
> Que devuelve los siguientes mensajes:
> #, #@ #add: #asParameter #at: #at:put:
> #class #do: #handle #height
> #invalidArgument #isNil #new
> #new: #nextPut: #notNil #size
> #value #value: #value:value: #x #y
Sí, creo que quede enganchado en pensar que quizás #atInstanceVar: se
resolviera tan inmediatamente como #at:.
De todos modos, como dije, era sólo una teoría interesante, y se puede validar
rápidamente mirando losliterales del método... Al aparecer allí el
#atInstanceVar:, comprobamos que la teoría era equivocada.
Saludos
--
Carlos E. Ferro
Caesar Systems
Hola!,
Lo que comenta Carlos es correcto, hay un puñado de
mensajes que no se envían en casi todos los Smalltalks.
Pero creo que este no es el caso que se presenta en
la situación que describió kiko.
Normalmente ese reemplazo (por byteCodes) se revela
por la ausencia del mensaje en los literales del método.
Creo que los mensajes que se cortocicuitan
en VS pueden verse con la expresion:
CompiledMethod specialSelectors keys
Que devuelve los siguientes mensajes:
#, #@ #add: #asParameter #at: #at:put:
#class #do: #handle #height
#invalidArgument #isNil #new
#new: #nextPut: #notNil #size
#value #value: #value:value: #x #y
hasta pronto,
Ale.
----- Original Message -----
From: "Carlos E. Ferro" <ceferro@...>
To: <smalltalking@...>
Sent: Tuesday, November 07, 2006 11:46 AM
Subject: Re: [objetos] RE:Cambio de instancia
On 7 Nov 2006 at 12:56, kikote gregoris wrote:
[ . . . ]
> ifTrue: [newInstance instVarAt: newPosition put: (oldInstance
> instVarAt: position)].
> position + 1].
>
> Se puede ver claramente que se le esta enviando un mensaje a la vieja
instancia que se llama
> anObsoletXXX.
> Esto se supone no es posible pues el comportamiento fue modificado para
que no entienda mas
> que el #doesNotUnderstand:aMessage.
> Lo cual es cierto si abro un inspector sobre dicha instancia y trato de
enviarle un mensaje.
> Como es posible que dentro de la ejecución si entienda #instVarAt: y sobre
un inspector no ¿?.
Te doy una teoría, no la verifiqué (se puede verificar viendo los bytecodes
y/o
literals del compiled method) pero igual es interesante:
Al compilar el método, el #instVarAt: no genera bytecodes para el envío de
ese
mensaje, sino que lo pasa a una operación directa de la Máquina Virtual.
Entonces, en la ejecución, como vos decís, los bytecodes andan bien, porque
no
se envía el mensaje. En el inspector, vos sí enviás el mensaje (se compila
en
otro contexto en el que no se aplica esa conversión del código) y no anda.
> No se si es algo natural lo que ocurra, pues en ciertos momentos me ocurre
que olvido conceptos
> básicos de la TO.
Esto no es un concepto básico de Teoría, sino un detalle de implementación.
Saludos
--
Carlos E. Ferro
Caesar Systems
Para más información sobre la Asociación escribir a info@...
Smalltalking es un espacio colaborativo creado para el estudio y desarrollo
en Ambientes de Objetos.
Se sustenta gracias a la participación de sus socios.
Las reglas de etiqueta sobre la lista están en
http://www.smalltalking.net/join/netiquete.htm
Enlaces de Yahoo! Grupos
On 7 Nov 2006 at 12:56, kikote gregoris wrote:
[ . . . ]
> ifTrue: [newInstance instVarAt: newPosition put: (oldInstance
> instVarAt: position)].
> position + 1].
>
> Se puede ver claramente que se le esta enviando un mensaje a la vieja
instancia que se llama
> anObsoletXXX.
> Esto se supone no es posible pues el comportamiento fue modificado para que no
entienda mas
> que el #doesNotUnderstand:aMessage.
> Lo cual es cierto si abro un inspector sobre dicha instancia y trato de
enviarle un mensaje.
> Como es posible que dentro de la ejecución si entienda #instVarAt: y sobre un
inspector no ¿?.
Te doy una teoría, no la verifiqué (se puede verificar viendo los bytecodes y/o
literals del compiled method) pero igual es interesante:
Al compilar el método, el #instVarAt: no genera bytecodes para el envío de ese
mensaje, sino que lo pasa a una operación directa de la Máquina Virtual.
Entonces, en la ejecución, como vos decís, los bytecodes andan bien, porque no
se envía el mensaje. En el inspector, vos sí enviás el mensaje (se compila en
otro contexto en el que no se aplica esa conversión del código) y no anda.
> No se si es algo natural lo que ocurra, pues en ciertos momentos me ocurre que
olvido conceptos
> básicos de la TO.
Esto no es un concepto básico de Teoría, sino un detalle de implementación.
Saludos
--
Carlos E. Ferro
Caesar Systems
Hola kiko,
Segun entiendo (sin ver la implementacion) la instancia obsoleta
no entiende ningún mensaje.
Al ser impactada por un mensaje, lo primero que debería ocurrir
es restaurar el methodDictionary original (para que se le puedan
enviar mensajes), luego se la debería copiar a una nueva instancia
(aquí la instancia obsoleta ya hereda metodos de instancia de
Object nuevamente) usando mensajes muy básicos; y por último
se haría el bendito #become: ; todo esto en una operación "atómica".
Creo que tu confusión viene porque pensas que el methodDictionary
se setea una sola vez... y estas olvidando que ante el primer impacto
de un mensaje se puede restaurar al valor anterior y usar el objeto
viejo tal cual como estaba antes de iniciar la mutación.
El usar el inspector, es algo complicado en estos casos;
y es insuficiente para entender que esta pasando abajo...
hasta pronto,
Ale.
----- Original Message -----
From: "kikote gregoris" <kikogregoris@...>
To: <smalltalking@...>
Sent: Tuesday, November 07, 2006 9:56 AM
Subject: [objetos] RE:Cambio de instancia
> Hola Gente
>
> Siguiendo con mis intentos por encontrar una solución a la mutación de
las instancias, me surge una pregunta que no me había echo anteriormente.
> Cundo se dispara el proceso de mutación ocurre algo que no había notado
y que no entiendo.
>
> Si detengo la ejecución en el siguiente método:
>
> transferNamedStateFrom: oldInstance to: newInstance
> "Copy values of named instances variables from the old
instance to the new instance"
> "This implementation preserves the values of any old
instances variables that still exist in the new instance, even if their
relative positions have changed"
>
> | targetPositions targetNames newPosition |
> "build a dictionary that maps instance variable names to
offsets in new instance"
> targetNames := self targetClass allInstVarNames.
> targetPositions := Dictionary new: targetNames size.
> targetNames inject: 1 into: [:position :name|
> targetPositions at: name put: position.
> position + 1].
>
> "Copy the value of each instance variable in the old
instances for which
> an identically named instance variable exists in the new
instance."
> self oldVariableNames inject: 1 into: [:position :name|
> newPosition := targetPositions at: name
ifAbsent: [0].
> newPosition ~= 0
> ifTrue: [newInstance instVarAt:
newPosition put: (oldInstance instVarAt: position)].
> position + 1].
>
> Se puede ver claramente que se le esta enviando un mensaje a la vieja
instancia que se llama anObsoletXXX.
> Esto se supone no es posible pues el comportamiento fue modificado para
que no entienda mas que el #doesNotUnderstand:aMessage.
> Lo cual es cierto si abro un inspector sobre dicha instancia y trato de
enviarle un mensaje.
> Como es posible que dentro de la ejecución si entienda #instVarAt: y
sobre un inspector no ¿?.
>
>
> No se si es algo natural lo que ocurra, pues en ciertos momentos me
ocurre que olvido conceptos básicos de la TO.
>
>
> Saludos kiko
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Siguiendo con mis intentos por encontrar una solución a la mutación de las instancias, me surge una pregunta que no me había echo anteriormente.
Cundo se dispara el proceso de mutación ocurre algo que no había notado y que no entiendo.
Si detengo la ejecución en el siguiente método:
transferNamedStateFrom: oldInstance to: newInstance
"Copy values of named instances variables from the old instance to the new instance"
"This implementation preserves the values of any old instances variables that still exist in the new instance, even if their relative positions have changed"
| targetPositions targetNames newPosition |
"build a dictionary that maps instance variable names to offsets in new instance"
Se puede ver claramente que se le esta enviando un mensaje a la vieja instancia que se llama anObsoletXXX.
Esto se supone no es posible pues el comportamiento fue modificado para que no entienda mas que el #doesNotUnderstand:aMessage.
Lo cual es cierto si abro un inspector sobre dicha instancia y trato de enviarle un mensaje.
Como es posible que dentro de la ejecución si entienda #instVarAt: y sobre un inspector no ¿?.
No se si es algo natural lo que ocurra, pues en ciertos momentos me ocurre que olvido conceptos básicos de la TO.
Saludos
kiko
__________________________________________________ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
> Todavía no intente esta solución ya que me surgió un nuevo problemita (esta
> vez le toco a opentalk con excepciones) que estoy solucionando y cuando lo
> consiga envío la solucion a ver que les parece.
Por si a alguien le sirve (Al final resulto ser una huevada)
La aplicación tiene una arq de cliente servidor distribuida con
Opentalk y yo en mi servidor (en mi modelo) disparaba excepciones y
esperaba capturarlas en el cliente (EJ LoginError), pero tenía el
problema que la excepcion no era enviada al cliente y me quedaba en el
servidor.
¿Cual era el problema?
Opentalk distribuye los errores (subclase de Error) pero con las
Exceptions no hace nada por eso es que mi error quedaba en el
servidor.
En fin, cambiando la superclase a Error salio andando.
PD: ahora le llega la hora a Omnibase
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
Pero el de OmniBase es otro paper, yo lo
puedo conseguir por que fue parte de mi tesis, pero tengo que ir hasta
facultad.
Saludos Bruno
De:smalltalking@... [mailto:smalltalking@...] En nombre de Alejandro F. Reimondo Enviado el: sábado, 04 de
noviembre de 2006 11:57 Para:smalltalking@... Asunto: Re: [objetos] Omnibase -
primeros pasos... primeros golpes
Bruno,
En nuestro sitio, en la página de documentos
hay un aporte tuyo de nombre
Artículo sobre Mapeo de Objetos en Bases de Datos Relacionales.
Por Bruno Brasesco.
Ale.
----- Original Message -----
From: "Bruno Buzzi Brassesco" <smalltalk@...>
To: <smalltalking@...>
Sent: Friday, November 03, 2006 6:55 PM
Subject: RE: [objetos] Omnibase - primeros pasos... primeros golpes
Gente,
Si alguien de la lista tiene un documento que habia hecho hace tiempo y se
lo puede mandar a "Chiara" estaria buenisimo.
(se que se lo envie a alguien pero no recuerdo a quien)
A mi hace un mes se hizo bolsa el disco duro, y no se si tengo ese documento
respaldado, y estoy muy escaso de tiempo.
Saludos
_____
De: smalltalking@...
[mailto:smalltalking@...]
En nombre de Chiara
Enviado el: viernes, 03 de noviembre de 2006 12:31
Para: smalltalking@...
Asunto: Re: [objetos] Omnibase - primeros pasos... primeros golpes
Hola Kiko, gracias por el "tip", ya estuve viendo (es mas, fue lo
primero
que hice :-)) los históricos pero sigo un poco colgado, mas qu nada porque
nunca toque nada de omnibase y no consigo ningún tuto....
On 11/3/06, kikote gregoris <kikogregoris@...> wrote:
Hola chiara
No se nada de OmniBase, pero puedo decirte que mires los históricos hay
mucha información sobre el tema.
Saludos kiko
Chiara < muralito@...> escribió:
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados
algún tuto que me explique un poco más que lo que hay en la web
oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación
distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por
referencia)). Estas vistas de los objetos deberían ser consistentes y
mantenerse consistentes a los cambios. En memoria me funciona todo
perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los
objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy
[*] que conozca el OID de cada instancia lebantada en memoria (este
proxi sería único por instancia) y que sepa como persistir el objeto
ante un cambio(simulando un markDirty en el proxy pero afuera de una
transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si
esto
o algo similar ya está implementado o si estoy encarando mal el uso de
omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con
Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas,
solo redirigiría las escrituras y se "actualizaría" en base a estas
escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a la BD con lo que la
performance decaería demasiado, y si no hago uno genérico, tendría que
implementar el proxy para cada clase persistente (cosa que no quiero
:-( )
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by
understanding."
Albert Einstein
__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by
understanding."
Albert Einstein
Hola,
>Los documentos interesantes se podrían al
> espacio que hay en esta lista de Yahoo.
Si!
Aprovecho a decirles además que si alguno de ustedes
escribe algún material relacionado con nuestros objetivos
(avances en T.O. usando Ambientes) desearíamos
incluirlos en nuestra página de lecturas recomendadas.
Ale.
pdta.: Actualmente la página de lecturas recomendadas
posee artículos muy variados y pocos aportes de gente
que participa de Smalltalking, sería muy bueno que
con el tiempo podamos incorporar material que sea
producto de nuestra actividad aquí y en otros medios.
----- Original Message -----
From: "Angel "Java" Lopez" <ajlopez@...>
To: <smalltalking@...>
Sent: Saturday, November 04, 2006 10:46 AM
Subject: Re: [objetos] Omnibase - primeros pasos... primeros golpes
Hola gente!
Los documentos interesantes se podrian al espacio que hay en esta lista de
Yahoo.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
----- Original Message -----
From: Bruno Buzzi Brassesco
To: smalltalking@...
Sent: Friday, November 03, 2006 6:55 PM
Subject: RE: [objetos] Omnibase - primeros pasos... primeros golpes
Gente,
Si alguien de la lista tiene un documento que habia hecho hace tiempo y se
lo puede mandar a "Chiara" estaria buenisimo.
(se que se lo envie a alguien pero no recuerdo a quien)
A mi hace un mes se hizo bolsa el disco duro, y no se si tengo ese
documento respaldado, y estoy muy escaso de tiempo.
Saludos
Gracias a todos por la respuestas, espero el tuto :-) mientras sigo intentando "mi camino" en omnibase. En otra lista me aconsejaron que para "salir del paso" utilice una transacción global que arranqu y termine con el sistema utilizando checkpoints intermedios. Todavía no intente esta solución ya que me surgió un nuevo problemita (esta vez le toco a opentalk con excepciones) que estoy solucionando y cuando lo consiga envío la solucion a ver que les parece.
-- Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding." Albert Einstein
Bruno,
En nuestro sitio, en la página de documentos
hay un aporte tuyo de nombre
Artículo sobre Mapeo de Objetos en Bases de Datos Relacionales.
Por Bruno Brasesco.
Ale.
----- Original Message -----
From: "Bruno Buzzi Brassesco" <smalltalk@...>
To: <smalltalking@...>
Sent: Friday, November 03, 2006 6:55 PM
Subject: RE: [objetos] Omnibase - primeros pasos... primeros golpes
Gente,
Si alguien de la lista tiene un documento que habia hecho hace tiempo y se
lo puede mandar a "Chiara" estaria buenisimo.
(se que se lo envie a alguien pero no recuerdo a quien)
A mi hace un mes se hizo bolsa el disco duro, y no se si tengo ese documento
respaldado, y estoy muy escaso de tiempo.
Saludos
_____
De: smalltalking@... [mailto:smalltalking@...]
En nombre de Chiara
Enviado el: viernes, 03 de noviembre de 2006 12:31
Para: smalltalking@...
Asunto: Re: [objetos] Omnibase - primeros pasos... primeros golpes
Hola Kiko, gracias por el "tip", ya estuve viendo (es mas, fue lo primero
que hice :-)) los históricos pero sigo un poco colgado, mas qu nada porque
nunca toque nada de omnibase y no consigo ningún tuto....
On 11/3/06, kikote gregoris <kikogregoris@...> wrote:
Hola chiara
No se nada de OmniBase, pero puedo decirte que mires los históricos hay
mucha información sobre el tema.
Saludos kiko
Chiara < muralito@...> escribió:
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados
algún tuto que me explique un poco más que lo que hay en la web
oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación
distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por
referencia)). Estas vistas de los objetos deberían ser consistentes y
mantenerse consistentes a los cambios. En memoria me funciona todo
perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los
objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy
[*] que conozca el OID de cada instancia lebantada en memoria (este
proxi sería único por instancia) y que sepa como persistir el objeto
ante un cambio(simulando un markDirty en el proxy pero afuera de una
transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto
o algo similar ya está implementado o si estoy encarando mal el uso de
omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con
Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas,
solo redirigiría las escrituras y se "actualizaría" en base a estas
escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a la BD con lo que la
performance decaería demasiado, y si no hago uno genérico, tendría que
implementar el proxy para cada clase persistente (cosa que no quiero
:-( )
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
Hola gente!
Una propuesta, para trabajar en Smalltalk. Aunque no queda claro si buscan
solamente los que no conozcan el lenguaje.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
To: vbnet List Member
Cc: vbnet@...
Sent: Friday, November 03, 2006 3:49 PM
Subject: [vbnet] Referencia para Propuesta Laboral
Estamos buscando profesionales para una importante empresa de
Telecomunicaciones.
Programadores Orientados a Objetos (POO), pueden ser programadores en C++ o
C# (NET) o java/J2EE que quieran programar con Smalltak.
Sólidos conocimientos en programación orientada a objetos. (POO) 2 años de
experiencia.
Desde ya muchisimas gracias. Atte. Ana.
Ana Spadoni
Piedras 338 Piso 3º Of. 13
Buenos Aires
(++54 11) 4343-5400/1225/1256
(++54 9 11) 15 4399-9481
ana.spadoni@...
www.lnsa.com.ar
Si alguien de la lista tiene un documento
que habia hecho hace tiempo y se lo puede mandar a “Chiara” estaria
buenisimo.
(se que se lo envie a alguien pero no
recuerdo a quien)
A mi hace un mes se hizo bolsa el disco
duro, y no se si tengo ese documento respaldado, y estoy muy escaso de tiempo.
Saludos
De:smalltalking@... [mailto:smalltalking@...] En nombre de Chiara Enviado el: viernes, 03 de
noviembre de 2006 12:31 Para:smalltalking@... Asunto: Re: [objetos] Omnibase -
primeros pasos... primeros golpes
Hola Kiko, gracias por el
"tip", ya estuve viendo (es mas, fue lo primero que hice :-)) los
históricos pero sigo un poco colgado, mas qu nada porque nunca toque nada de
omnibase y no consigo ningún tuto....
estoy dando mis primeros pasos en Omnibase y busque por todos lados
algún tuto que me explique un poco más que lo que hay en la web
oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación
distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por
referencia)). Estas vistas de los objetos deberían ser consistentes y
mantenerse consistentes a los cambios. En memoria me funciona todo
perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los
objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy
[*] que conozca el OID de cada instancia lebantada en memoria (este
proxi sería único por instancia) y que sepa como persistir el objeto
ante un cambio(simulando un markDirty en el proxy pero afuera de una
transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si
esto
o algo similar ya está implementado o si estoy encarando mal el uso de
omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con
Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas,
solo redirigiría las escrituras y se "actualizaría" en base a estas
escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a la BD con lo que la
performance decaería demasiado, y si no hago uno genérico, tendría que
implementar el proxy para cada clase persistente (cosa que no quiero
:-( )
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by
understanding."
Albert Einstein
__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by
understanding."
Albert Einstein
Si hay alguien en la lista que tenga el documento que habia hecho de OmniBase y se lo puede mandar a "Chiara". Se que se lo envie a alguien y no recuerdo a quien.
A mi hace un mes se me hizo pedazos el disco, y no se si tendre respaldado ese documento, y en estos momentos ando muy muy escaso de tiempo.
El fin de semana quizas me haga un tiempo y pueda mandar lo que tengo pasado de transacciones y sesiones con los Presenters, se que no esta terminado, pero puedo responder las dudas por mail, por que no voy a tener tiempo de terminarlo.
saludos bruno
----Mensaje original---- De: muralito@... Fecha: 03/11/2006 09:09 Para: Asunto: [objetos] Omnibase - primeros pasos... primeros golpes
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados algún tuto que me explique un poco más que lo que hay en la web oficial (demasiado básico para mi gusto) y al ser la primera vez que intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación distribuida con opentalk (aunque funciona como cliente servidor, donde los clientes solo tienen las vistas(el modelo se pasa por referencia)). Estas vistas de los objetos deberían ser consistentes y mantenerse consistentes a los cambios. En memoria me funciona todo perfecto, pero a la hora de intentar persistir con Omnibase tengo un pequeño problema que es que los objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy [*] que conozca el OID de cada instancia lebantada en memoria (este proxi sería único por instancia) y que sepa como persistir el objeto ante un cambio(simulando un markDirty en el proxy pero afuera de una transacción). De esta manera, las vistas se montarían sobre los proxis y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto o algo similar ya está implementado o si estoy encarando mal el uso de omnibase, por otro lado tendría que adaptar todo mi sistema (las vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas, solo redirigiría las escrituras y se "actualizaría" en base a estas escrituras. El problema de esto es que si quisiera hacer un proxy completamente genérico, redirigiría las lecturas a la BD con lo que la performance decaería demasiado, y si no hago uno genérico, tendría que implementar el proxy para cada clase persistente (cosa que no quiero :-( )
-- Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding." Albert Einstein
Hola Kiko, gracias por el "tip", ya estuve viendo (es mas, fue lo primero que hice :-)) los históricos pero sigo un poco colgado, mas qu nada porque nunca toque nada de omnibase y no consigo ningún tuto....
estoy dando mis primeros pasos en Omnibase y busque por todos lados algún tuto que me explique un poco más que lo que hay en la web oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por referencia)). Estas vistas de los objetos deberían ser consistentes y mantenerse consistentes a los cambios. En memoria me funciona todo perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy [*] que
conozca el OID de cada instancia lebantada en memoria (este proxi sería único por instancia) y que sepa como persistir el objeto ante un cambio(simulando un markDirty en el proxy pero afuera de una transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto o algo similar ya está implementado o si estoy encarando mal el uso de omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas, solo redirigiría las escrituras y se "actualizaría" en base a estas escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a
la BD con lo que la performance decaería demasiado, y si no hago uno genérico, tendría que implementar el proxy para cada clase persistente (cosa que no quiero :-( )
-- Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
__________________________________________________ Correo Yahoo! Espacio para todos
tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
-- Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding." Albert Einstein
Hola Chiara,
Como lectura adicional a la que puedas encontrar de Omnibase,
y relacionada con esquemas de persistencia de objetos;
me parece muy recomendable los manuales (y tutoriales)
de VOSS.
La página del proveedor es http://www.logicarts.com/
allí vas a encontar algunos comentarios técnicos que
me parecen importantes leer para tener mas idea
acerca de la problemática y alternativas de solución
de persistir sub-espacios de objetos.
Recuerdo (bien?) que hace unos años tenían los manuales
para bajar del sitio, ahora no los veo; pero seguramente
si pedís que te envíen la versión de evaluación, los incluye...
Considerá lo que te digo, en función de facilitar material adicional
de lectura, adicional al que conseguirás para Omnibase y que
seguramente te acercarán algunas personas de la
lista que lo utilizan.
que lo disfrutes!,
Ale.
----- Original Message -----
From: "Chiara" <muralito@...>
To: <smalltalking@...>
Sent: Friday, November 03, 2006 9:09 AM
Subject: [objetos] Omnibase - primeros pasos... primeros golpes
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados
algún tuto que me explique un poco más que lo que hay en la web
oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación
distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por
referencia)). Estas vistas de los objetos deberían ser consistentes y
mantenerse consistentes a los cambios. En memoria me funciona todo
perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los
objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy
[*] que conozca el OID de cada instancia lebantada en memoria (este
proxi sería único por instancia) y que sepa como persistir el objeto
ante un cambio(simulando un markDirty en el proxy pero afuera de una
transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto
o algo similar ya está implementado o si estoy encarando mal el uso de
omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con
Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas,
solo redirigiría las escrituras y se "actualizaría" en base a estas
escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a la BD con lo que la
performance decaería demasiado, y si no hago uno genérico, tendría que
implementar el proxy para cada clase persistente (cosa que no quiero
:-( )
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
Para más información sobre la Asociación escribir a info@...
Smalltalking es un espacio colaborativo creado para el estudio y desarrollo
en Ambientes de Objetos.
Se sustenta gracias a la participación de sus socios.
Las reglas de etiqueta sobre la lista están en
http://www.smalltalking.net/join/netiquete.htm
Enlaces de Yahoo! Grupos
No se nada de OmniBase, pero puedo decirte que mires los históricos hay mucha información sobre el tema.
Saludos kiko
Chiara <muralito@...> escribió:
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados algún tuto que me explique un poco más que lo que hay en la web oficial (demasiado básico para mi gusto) y al ser la primera vez que intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación distribuida con opentalk (aunque funciona como cliente servidor, donde los clientes solo tienen las vistas(el modelo se pasa por referencia)). Estas vistas de los objetos deberían ser consistentes y mantenerse consistentes a los cambios. En memoria me funciona todo perfecto, pero a la hora de intentar persistir con Omnibase tengo un pequeño problema que es que los objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy [*] que
conozca el OID de cada instancia lebantada en memoria (este proxi sería único por instancia) y que sepa como persistir el objeto ante un cambio(simulando un markDirty en el proxy pero afuera de una transacción). De esta manera, las vistas se montarían sobre los proxis y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto o algo similar ya está implementado o si estoy encarando mal el uso de omnibase, por otro lado tendría que adaptar todo mi sistema (las vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas, solo redirigiría las escrituras y se "actualizaría" en base a estas escrituras. El problema de esto es que si quisiera hacer un proxy completamente genérico, redirigiría las lecturas a
la BD con lo que la performance decaería demasiado, y si no hago uno genérico, tendría que implementar el proxy para cada clase persistente (cosa que no quiero :-( )
-- Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding." Albert Einstein
__________________________________________________ Correo Yahoo! Espacio para todos
tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Hola, lista
estoy dando mis primeros pasos en Omnibase y busque por todos lados
algún tuto que me explique un poco más que lo que hay en la web
oficial (demasiado básico para mi gusto) y al ser la primera vez que
intento algo en omnibase estoy un tanto perdido.
Mi mayor problema es con la metodología de trabajo de transacciones.
Para explicar un poquito más, lo que yo tengo es una aplicación
distribuida con opentalk (aunque funciona como cliente servidor, donde
los clientes solo tienen las vistas(el modelo se pasa por
referencia)). Estas vistas de los objetos deberían ser consistentes y
mantenerse consistentes a los cambios. En memoria me funciona todo
perfecto, pero a la hora de intentar persistir con Omnibase tengo un
pequeño problema que es que los
objetos persistidos no escapan a las transacciones.
Una de las cosas que había pensado es desarrollar una especie de proxy
[*] que conozca el OID de cada instancia lebantada en memoria (este
proxi sería único por instancia) y que sepa como persistir el objeto
ante un cambio(simulando un markDirty en el proxy pero afuera de una
transacción). De esta manera, las vistas se montarían sobre los proxis
y con eso "arreglaría" las cosas. Mi problema aca es que no se si esto
o algo similar ya está implementado o si estoy encarando mal el uso de
omnibase, por otro lado tendría que adaptar todo mi sistema (las
vistas) para usar el "modelo" de los proxy y no el real.
Si alguien tiene algún tutorial que explique como trabajar bien con
Omnibase y me lo puede acercar (mandar por mail :P) se lo agradecería
demasiado.
[*]no sería proxy completo pues cachearía los datos para las lecturas,
solo redirigiría las escrituras y se "actualizaría" en base a estas
escrituras. El problema de esto es que si quisiera hacer un proxy
completamente genérico, redirigiría las lecturas a la BD con lo que la
performance decaería demasiado, y si no hago uno genérico, tendría que
implementar el proxy para cada clase persistente (cosa que no quiero
:-( )
--
Saludos Chiara
"Peace cannot be kept by force; it can only be achieved by understanding."
Albert Einstein
Hola Elvio,
[disculpa la demora]
>Por eso cite los puntes (6) y (8) por ahí están bastante
> entrelazados estos dos.
>Otra forma de verlo, es lo que dejas implícito en tu comentario del punto
>(8). Un "cambio de forma" (quizás) remite a un cambio estructural/orgánico.
>Como los que se pueden operar en una imagen de Smalltalk.
El problema de plantear evolución como cambios sucesivos (a mi entender)
es que implicaría que hay cambios que son "apropiados" y otros que
no para que haya evolución; es decir, implica una voluntad "suprema"...
(no digo que no la haya, sino que es innecesario hacer valer
esa voluntad para un tema tan menor como definir evolución :)
En mi opinión, es suficiente definirla en base a la percepción de un
conjunto de emergentes que YA se han dado en un sistema; es
decir, definirla cuando ya es un observable y no como algo
a futuro en un sistema.
Por otro lado, estos emergentes podrían ser usados para sentir que
un ambiente[*] ha evolucionado, si son expresables en términos de
especies (en base a especiación; relaciones orgánicas) y
no en base a "cambios de" instancias específicas
(o un conjunto de ellas, aSet o aClass)
[*] un sistema abierto, no me parece correcto plantear
evolución en sistemas cerrados.
>Ale ,no paro de pensar en tu trabajo de gestación de imágenes.
> Se podría dar el caso de una gestación sexuada donde el embrión
> sea no-funcional por tener padres incompatibles??
Si, creo que puede ser tan frecuente como que un
image en particular caiga en manos de un aprendiz
que lo use para ver que pasa si borra algunos métodos
de Object... (esos individuos no sobreviven...
y por eso no cuentan en la evolución de Smalltalk?
seguro?)
>En el furor de la programación estructurada, no hubo
> emergentes? (no importa si fueron positivos o negativos)
Un emergente es algo que se siente...
Podes sentir o no... es una actitud que uno toma
frente a lo que ya paso.
La forma en que usamos esa información (en-formación)
y hasta dónde reconocemos los efectos de nuestro
método es lo que distingue a alguien que usa un método
formal de quien lo complementa con actividades no formales.
Que quiero decir?...
No pongas a quienes usamos el concepto de ambiente en
la vereda de enfrente de quienes no lo usan, nuestra
forma de actuar es complementaria con la tradicional,
no contraria a ella.
Todo lo que hablamos aquí complementa lo comúnmente
usado, entre otras cosas la estructuración y usos varios
del encapsulamiento.
>Se puede hablar de "evolución" en la informática? o solo son
>reformulaciones?
>Si son solo reformulaciones, entonces lo veo como que el Paradigma de
>Objetos es una reformulacion para inhibir/castrar efectos secundarios
>(quizás emergentes) de el paradigma procedural. (uy! en qué berengenal me
>meti!!)
Si pensas en términos de fórmulas (paradigmas) no es posible
plantear mas que cambios sucesivos... que justamente en el caso
de los paradigmas, son ortogonales, luego ni siquiera podemos
plantear seriamente relaciones de parentesco.
Es decir, podemos dejar de lado el paradigma, y entender que
es una formula interesante para introducir en el tema
a principiantes...
>También me confunde un poco porque en el termino "evolución" quizás estoy
>volcando la noción de "mejoramiento" y no se si solamente debería tomarlo
>como una "transformación".
>El "mejoramiento" en la evolución natural no esta ligado a la adaptabilidad
>en el contexto? Esto seria aplicable al soft?
El asociarlo con una mejora general implica que
se lo está usando como política. Muchas veces
encuentro que se usan términos como evolución,
natural, ecológico, para incentivar la apertura de
quienes escuchan (para que no objeten críticamente
a quienes están diciendo otras cosas en el mismo párrafo :)
>Bueno... disculpas por mi discurrir azaroso.
gracias por hacerlo y compartirlo!
hasta pronto,
Ale.
----- Original Message -----
From: "Elvio Fernandez" <elvio.fernandez@...>
To: <smalltalking@...>
Sent: Friday, October 20, 2006 12:31 PM
Subject: Re: [objetos] Volviendo al tema de la evolución...
Gente esta charla esta buenisima!
Tengo poco tiempo por dia, pero me hago el lugar para ir leyendo y no paro
de hacerme preguntas.
Ale decia:
"6.- Mudanza de conducta, de propósito o de actitud.
Interesante, incluye comportamiento y tiempo;
sin manchar la definición con actores ni voluntades.
[...]
8.- Cambio de forma.
Eso, segun entiendo es mutación.
Asociar mutacion con evolucion es innecesario;
incluso (pienso, aqui como muchos otros) que
es incorrecto hablar de evolución en un
individuo (una instancia)."
Cuando hablas de mutacion quizas sera que lo estas interpretando como un
cambio abrupto en un individuo? en este caso una instancia. (Que despelote
de interpretaciones :) )
Quizas un cambio de forma implique una transformacion, a traves de estadios
sucesivos.
Por eso cite los puntes (6) y (8) por ahi estan bastante entrelazados estos
dos.
Otra forma de verlo, es lo que dejas implicito en tu comentario del punto
(8). Un "cambio de forma" (quizas) remite a un cambio estructural/organico.
Como los que se pueden operar en una imagen de Smalltalk.
Ale ,no paro de pensar en tu trabajo de gestacion de imagenes. Se podria dar
el caso de una gestacion sexuada donde el embrion sea no-funcional por tener
padres incompatibles??
Ale decia:
"Por otra parte, en un ambiente (sistema abierto),
hay posibilidad de observar emergentes sistémicos que
sobrepasan la capacidad de entendimiento de sus creadores/autores.
Uno, al reflexionar sobre esos emergentes, se puede
dar cuenta cual es nuestro rol en esos sistemas; y decir,
este sistema evolucionó.
Dónde la evolución es un observable (algo que uno siente
que YA PASO) y no algo que puede predecirse ni
garantizarse (ni proyectarse) en el futuro."
No se bien como interpretar esto. Me confunde un poco. En el furor de la
programacion estructurada, no hubo emergentes? (no importa si fueron
positivos o negativos)
Se puede hablar de "evolucion" en la informatica? o solo son
reformulaciones?
Si son solo reformulaciones, entonces lo veo como que el Paradigma de
Objetos es una reformulacion para inhibir/castrar efectos secundarios
(quizas emergentes) de el paradigma procedural. (uy! en qué berengenal me
meti!!)
Tambien me confunde un poco porque en el termino "evolucion" quizas estoy
volcando la nocion de "mejoramiento" y no se si solamente deberia tomarlo
como una "transformacion".
El "mejoramiento" en la evolucion natural no esta ligado a la adaptabilidad
en el contexto? Esto seria aplicable al soft?
Bueno... disculpas por mi discurrir azaroso.
Saludos
Elvio
Hola,
> Estaba tratando de cambiar el MethodDictionary de la clase
> para ver que pasaba con las instancias, en VS no hay drama
>le coloque uno vacío y la instancia ya no respondía a ningún
> mensaje y en el browser de clases los mensaje ya no existían.
> Me fui a MT para hacer lo mismo, tome el Core::ClassDescriptor
> de la clase le coloque un StringDictionary vacío a una variable
> que conoce a los métodos.
> Luego fui a la instancia y le mande un mensaje, con el
> sorprendente resultado de que me lo contesto sin ningún problema.
Es consistente con que sea una "descripción" :-)
Cuando tenes un objeto y su descripción, son dos cosas distintas...
> Fui al browser y los mensajes no existían, recompile la clase
> para ver que pasaba y nada la instancia seguía vivita y
> coleando respondiendo a los mensajes enviados.
> Luego me puse a ver como se hacían las llamadas
> a los métodos y encontré que se hace de la siguiente forma.
[ recorté la implemantacion...
larga y que parece escrita en basic :-P ...]
> No es todo el método es una parte pues es mucho
> mas largo, pero si todo va bien se termina llamando
> a lo que remarque.
...se termina ejecutando lo que marqué... :-)
> Además se puede llamar directamente
> a un método de la siguiente manera:
"llamar" ? te referís seguramente a "activar un método"
en un contexto dado...
o simplemente enviar unmensaje a un objeto receptor?
Activar un método en un contexto dado es innecesario,
normalmente se envía mensajes a objetos...
Para enviar un mensaje simplemente
0.- se lo envias...
Si el mensaje es distinto cada vez, podes:
1.- instanciar un mensaje (aMessaje) y enviarle #perform
2.- al objeto enviarle un #perform:... por ejemplo
miObjeto
perform: #tomaA:yA:
withArguments: (Array with: 1 with: otroObjeto)
> MemoryManager call: (self methodAddressAt:#hola) receiver: self .
> Donde self es el objeto en cuestión.
Segun 0: self hola.
Segun 1: (Message receiver: self selector: #hola) perform.
Segun 2: self perform: #hola.
> Quería saber como se resuelven las llamadas a los métodos
> en VS y si tiene algo de parecido con esto??.
Se envían mensajes :-)
El envío de un mensaje puede desencadenar la activación
de un método (que tenga la clase, o el objeto par atender
dicho mensaje)... o no.
> También me confunde el hecho de que al reemplazar
> el MethodDictionary por uno vacío la instancia sigue
> respondiendo los mensajes que tenia definido, cosa
> que no pasa en VS.
Leete el manual :-)
Lo digo en serio, seguramente hay algo que no estas
conociendo de la arquitectura subyacente.
Viendo dentro del image quizás no sea claro,
ni necesita estar expuesto claramente el porqué
ocurre lo que estas viendo.
hasta pronto,
Ale.
----- Original Message -----
From: "kikote gregoris" <kikogregoris@...>
To: <smalltalking@...>
Sent: Thursday, November 02, 2006 11:05 AM
Subject: [objetos] RE:Cambio de instancia
> Hola gente
>
>
> Estaba tratando de cambiar el MethodDictionary de la clase para ver que
pasaba con las instancias, en VS no hay drama le coloque uno vacío y la
instancia ya no respondía a ningún mensaje y en el browser de clases los
mensaje ya no existían.
> Me fui a MT para hacer lo mismo, tome el Core::ClassDescriptor de la
clase le coloque un StringDictionary vacío a una variable que conoce a los
métodos.
> Luego fui a la instancia y le mande un mensaje, con el sorprendente
resultado de que me lo contesto sin ningún problema.
> Fui al browser y los mensajes no existían, recompile la clase para ver
que pasaba y nada la instancia seguía vivita y coleando respondiendo a los
mensajes enviados.
>
> Luego me puse a ver como se hacían las llamadas a los métodos y
encontré que se hace de la siguiente forma.
>
>
> self _try: [
> result := MemoryManager call:
methodVA receiver: anObject.
> ]
> _filter: [ :code :exceptionPointers |
> " Bring up a walkback dialog "
> code
> case: EXCEPTION_STACK_OVERFLOW
perform: [
> fRepairStack := true.
> EXCEPTION_EXECUTE_HANDLER
> ]
> case:
ST_EXCEPTION_COMPILER_INVALID_POOL
> case:
ST_EXCEPTION_COMPILER_DUPLICATE_VARIABLE
> case:
ST_EXCEPTION_COMPILER_INCORRECT_SUPERCLASS
> case:
ST_EXCEPTION_COMPILER_INCORRECT_CLASS_DECL perform: [
> nilDic removeKey: 'DoIt'
asStringA.
> UndefinedObject
installMethod: #DoIt asInteger
> address:
(Object _methodAddressAt: #yourself).
> except_record :=
EXCEPTION_RECORD fromAddress:
>
(MemoryManager atAddress: exceptionPointers).
> except_record at: 24 put:
szDoIt basicAddress.
> EXCEPTION_CONTINUE_SEARCH
> ]
> case: ST_EXCEPTION_MEMORY_ERROR
perform: [
> WINAPI MessageBox: NULL
> with:
(Processor getMessages formatMsg: MSG_SRTERR_MEMALLOC with: 0)
> with: 'Fatal
Error'
> with:
MB_ICONSTOP|MB_OK.
> EXCEPTION_EXECUTE_HANDLER
> ]
> default: [
> exception := WinException
exceptionCode: code exceptionPointers: exceptionPointers.
> debugger notNil ifTrue: [
>
thisApplication unhandledException: exception
> ]
> ifFalse: [
> filterCode :=
exception unhandledException: NULL.
> filterCode ~=
EXCEPTION_CONTINUE_EXECUTION ifTrue: [
>
filterCode := EXCEPTION_EXECUTE_HANDLER
> ].
> filterCode
> ]
> ]
> ]
> _except: [
> fRepairStack ifTrue: [
> " try to recover from a
stack overflow "
> WINAPI StRepairStack.
> MessageBox logMessage:
MSG_STDERR_COMPILER_STACKFAULT
> ]
> ].
> nilDic removeKey: 'DoIt' asStringA.
> UndefinedObject installMethod: #DoIt asInteger
> address: (Object _methodAddressAt:
#yourself).
>
>
> No es todo el método es una parte pues es mucho mas largo, pero si todo
va bien se termina llamando a lo que remarque.
> Además se puede llamar directamente a un método de la siguiente manera:
>
> MemoryManager call: (self methodAddressAt:#hola) receiver: self .
> Donde self es el objeto en cuestión.
>
> Quería saber como se resuelven las llamadas a los métodos en VS y si
tiene algo de parecido con esto??.
> También me confunde el hecho de que al reemplazar el MethodDictionary
por uno vacío la instancia sigue respondiendo los mensajes que tenia
definido, cosa que no pasa en VS.
>
> Saludos kiko
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Hola,
> Me refería al hecho de si es posible sacar alguna conclusión
> sobre la validez o no de alguna de las 2 soluciones, si el caso
> que describo es muy habitual o no, y si debería preocuparme
> por que ocurra.
Preocupate cuando la solución no alcance para tus necesidades :-)
De esta forma estarás dándole importancia cuando estes
preparado para enfrentar el desafío y además con al menos
un caso concreto que te guíe sobre qué debes mejorar (en que
condiciones concretas).
El caso concreto que se presenta cuando algo no nos alcanza
es mucho mas rico que el que podemos tener de un planteo
abstracto de mejora...
Trata de avanzar siempre mirando hacia atras, considerando
lo que tenes hoy que lograr.
Dejá para mañana los problemas de mañana :-)
> No trataba de comparar en velocidad a MT con VS solo
> se me ocurrió hacer esta prueba y quise compartir los resultados.
Una de las razones de perdidas de perfomance en operaciones
que impliquen become u operaciones similares
es la cantidad de objetos (en espacios nuevos)
que hay en el sistema, memoria disponible, etc...
Hacer comparativas entre dos sistemas con VMs distintas,
uno que recolecta basura y otro que no, etc...
no es, en mi opinión de valor, pues se trata de sistemas
muy distintos y que incluso escalarán distintos...
hasta pronto,
Ale.
> Saludos kiko
>
>
> "Alejandro F. Reimondo" <aleReimondo@...> escribió: Hola
kiko,
>
> > Se pude sacar alguna conclusión de estos números??.
>
> Cual sería la pregunta que estas tratando resolver?
> Que la motiva?
>
> Lo digo porque no entiendo porque comparás
> MT con VS en velocidad, no encuentro un caso
> en dónde yo dudaría de usar uno u otro.
>
> > No parece ser tan catastrófico usar #allInstances.
> No lo es.
> Pero es una de las cosas que uno debe tratar de evitar,
> si piensa que puede ser posible.
>
> hasta pronto,
> Ale.
>
>
> ----- Original Message -----
> From: "kikote gregoris" <kikogregoris@...>
> To: <smalltalking@...>
> Sent: Tuesday, October 31, 2006 10:56 PM
> Subject: [objetos] Caso de Prueba en Cambio de instancias
>
>
> > Hola Gente
> >
> > Estuve probando el peor caso para la implementación de VS.
> > Genere una colección de 1000 objetos y luego modifique su clase, luego
> la recorrí enviándole un mensaje a cada objeto para obligarlos a mutar.
> > Medí el tiempo que se tomo y tardo 13 segundos.
> > Luego implemente una versión trucha para MT donde para mutar uso
> #allInstances y realice algo parecido a lo de VS.
> > Tardo 3 segundos para 1000.
> >
> > Se pude sacar alguna conclusión de estos números??.
> > El ejemplo no incluye la generación de la colección solo la recorrida
y
> mutación.
> > No parece ser tan catastrófico usar #allInstances.
> >
> > Por ultimo tengo otra pregunta.
> > En VS la clase se recopila y listo, quiero decir que el St no pregunta
> si quiero recompilar, solo lo hace y punto.
> > En MT una clase no se recompila si uno no da la orden de que se haga,
se
> que es una pregunta para hacerle a quien realizo el MT pero por hay tiene
> una sospecha de por que se hace esto.
> >
> > Saludos kiko
> >
> > PD: No se me ocurre una peor situación para probar en VS.
> > Copio algunas de las diferencias que tiene el MT sobre otros ST.
> > Aquí se destacan los beneficios de algunas de las diferencias. Si
tienen
> tiempo de leer algo para opinar estaría buenísimo
> >
> >
> > Differences with other Smalltalk Dialects This section depicts the
> differences that may exist with other Smalltalk dialects. In general,
> Smalltalk MT tries to follow existing implementation options for the sake
of
> compatibility.
> > Compiler options allow you to increase the compatibility at the
expense
> of code size and / or performance.
> > Pool Dictionaries reside in the sources In Smalltalk MT, Pool
> Dictionaries behave exactly like include files in C, i.e., they are part
of
> the source base. Other Smalltalk implementations usually design pool
> dictionaries as global variables. In Smalltalk MT, a pool dictionary is
not
> directly accessible from the image. You edit pool dictionaries by invoking
> the pool editor from the Options menu in the Class Hierarchy Browser. You
> can also load include files, and save a Smalltalk pool dictionary as an
> include file or as a Smalltalk chunk file.
> > Benefit: Reduced runtime requirements
> >
> > Symbols are not instances of String In Smalltalk MT, a symbol is a
byte
> object whose 32 bit value is an index into the symbol table. Because of
this
> indirection, symbols are not unique (although their associated value is).
> The benefit of this approach is that the symbol table is not required
during
> runtime, which substantially reduces the executable's size.
> > Optionally, Smalltalk MT can be configured to use identity symbols.
> > Benefit: Reduced runtime requirements
> >
> > Smalltalk is a class, not a dictionary In Smalltalk MT, the class
> Smalltalk takes over the functionality of the Smalltalk global variable
> present in most dialects. Smalltalk MT internally uses two dictionaries,
> SmalltalkGlobalDictionary for global variables, and
SmalltalkClassDictionary
> for classes. Class Smalltalk implements also linking with an external
> Smalltalk DLL.
> >
> > Two types of global variables: process-global and thread-local
variables
> Smalltalk MT introduces thread local variables variables. Once declared, a
> thread-local variable exists in all threads, but its value is specific to
> each thread.
> > Global variables are visible from all threads.
> >
> > Metaclasses are created on demand A Metaclass is created on demand by
> sending the message #class to a class.
> > Benefit: Reduced storage requirements.
> >
> > Issues when adding methods to base classes In some cases, new methods
> cannot be installed directly in certain base classes, such as Array,
> LargeInteger, MappingTable, StringA. In these cases, the compiler saves
the
> source code and emits a warning that the changes will not go into effect
> until the image is compressed. You must compress and restart the image to
> validate the modifications.
> > Note that this applies only to new methods and under certain
conditions;
> once installed, methods can be modified interactively.
> >
> > Simplified API Interface Before you can call an API, your image must
be
> linked with the appropriate DLL. Once this is done, you can call an API
with
> the keyword WINAPI.
> > Because objects never move in Smalltalk MT, you can directly pass
> objects as API arguments. Callbacks from non-Smalltalk code are also
> painless; any block can be passed as an API argument and called by
> non-Smalltalk code. Class methods can also be called, provided they belong
> to one of the Export categories.
> > Before an object is handed over to an API, it receives the hidden
> message #asCinteger. This message asks the receiving object for its 32 bit
> API representation. For example, a Window will answer the API
representation
> of its handle.
> > Note: Smalltalk MT also supports dynamic binding, which loads a DLL
when
> needed at runtime. However, the programming interface is identical, which
> makes it easy to switch between the two modes.
> >
> > Local Variables are uninitialized (optional) For performance reasons,
> local variables in static contexts (method contexts without blocks) are
> uninitialized (like in C compilers). Using an uninitialized local variable
> generates a compilation error. However, an uninitialized state may go
> undetected accurately if conditional statements are used.
> > Note: You can enable and disable local variable initializations in the
> language properties.
> >
> > String Literals in methods are merged (optional) In order to save
> space, a literal string (or any other literal byte object) that occurs
> several times inside a method is only stored once. A side-effect is that
an
> expression such as:
> > 'abc' == 'abc'
> > evaluates to true.
> >
> > Literal Strings accept escape characters Literal strings can be
> specified using escape characters, introduced by '\'. The syntax is
largely
> C-compliant. A consequence is that ordinary backslashes must be doubled.
> >
> > Other Differences in the Class Hierarchy File
> > Smalltalk MT has no actual File class. The functionality is taken over
> by FileStream. The identifier File is aliased to FileStream in order to
> support existing code.
> > A FileStream does not support some of the Stream methods that work at
> the byte granularity level. This would be inefficient because FileStream
> does not buffer I/O. MemoryStream should be used instead, because it takes
> advantage of the memory-mapped file system exposed by Win32.
> >
> > Dictionary Smalltalk MT uses MappingTable by default. Dictionary is
> aliased to MappingTable in order to preserve existing code.
> >
> > Name aliasing The compiler accepts alternate identifiers for some
> classes. The alternate name lookup has the least precedence, so it doesn't
> interfere with existing classes. Installing a class that has an aliased
name
> overrides the alias.
> > Example
> > By default, Dictionary is an alias for MappingTable. The extra
Smalltalk
> project installs a class Dictionary that is defined as a Set of
Associations
> (and therefore compatible with the original definition of Dictionary).
> Source code that references Dictionary will automatically refer to the new
> class when the project is installed, and to MappingTable when the project
is
> removed.
> >
> >
> > Frequently Asked Questions Table of Contents
> > Deliverable Files
> > Questions about source code strategy
> > What is the purpose of the message #_asCinteger ?
> > Is there a Notifier in Smalltalk MT?
> > What is the purpose of the window property 'STOBJ'?
> > ApplicationProcess allInstances is empty
> > I evaluated the following: [ ^self ] fork, and it raises an exception
> > Getting Started with Projects...
> > Building an Executable
> > Debugging an Executable
> > Miscellaneous Memory Allocation Questions
> > How do I stop a thread?
> > How do I exit Smalltalk MT by program?
> > MappedObjectStream only stores one object
> > Closing a memory-mapped file while keeping a reference generates
> exception
> > Saving an image over the network
> > Problems saving an image
> > Sample Code: Loading and unloading ActiveX Controls dynamically
> > Thread storage and blocks
> > I cannot access Transcript from another thread
> >
> > ---------------------------------
> >
> > Deliverable Files What follows is a description of the files that you
> must or may ship with a Smalltalk MT executable:
> > File
> > Description
> > Status
> > strtdll25.DLL
> > runtime routines for ST/MT (15kB)
> > required
> > stsrl.DLL
> > serialization routines (60kB)
> > optional - used by memory-mapped files and object serialization
> > stolestd.DLL
> > OLE helper library (44kB)
> > optional - used by some OLE / ActiveX classes
> > Back To Top
> >
> > ---------------------------------
> >
> > Source code strategy and naming conventions Class libraries
> > Smalltalk MT only implements classes / methods that are also used by
> the development environment or samples. That way, all source code has been
> tested.
> > Underscores
> > Underscores identify private messages, classes, or pseudo-messages
> (inlined messages).
> > Back To Top
> >
> > ---------------------------------
> >
> > What is the purpose of #_asCinteger? The message #_asCinteger is sent
> implicitly to API arguments, and returns a 32 bit representation of an
> object. If the object cannot be passed to an API (for example nil), it
> raises an exception.
> > You can bypass this message with one of the messages #basicAddress,
> #_asInteger, or more generally with an inline message that returns a known
> type (such as #_longAtOffset:).
> > Note that the address manipulation methods (#atAddress:put: etc.) do
not
> send the message, so you may have to send it yourself if the parameter is
> not an integer or LONG type.
> > Example: MemoryManager atAddress: ppEnumConnectionPoints put: ienum
> _asCinteger.
> > Back To Top
> >
> > ---------------------------------
> >
> > Does Smalltalk MT have a Notifier? Each window implements its own
> window procedure (although most windows inherit the default window
procedure
> in Window), and exports it to the operating system.
> > A Smalltalk-created window other than a dialog box reserves private
data
> in its window creation structure, and stores the address of the Smalltalk
> object in that slot (remember: in ST/MT, objects are never moved).
> > A DialogBox functions exactly like a Dialog Box in C/C++ ; each
instance
> has its own dialog procedure that references the Smalltalk object.
> > Back To Top
> >
> > ---------------------------------
> >
> > What is the purpose of the window property 'STOBJ' that is associated
> with a window? The purpose of this property is to be able to retrieve the
> Smalltalk object associated with a window, given the window handle. If the
> window is not maintained by Smalltalk (i.e., the window procedure is
> implemented elsewhere), the property will not be set.
> > Back To Top
> >
> > ---------------------------------
> >
> > I evaluated the following: [ ^self ] fork, and it raises an exception
> The return statement in a block returns from the method that defines the
> block. If you create a thread that executes this block, the new thread
would
> attempt to return from a method context in a parallel thread, therefore
> switching the stack and crashing. And your original thread would crash as
> well because the other thread corrupted its stack. Therefore, the code
that
> actually returns verifies that the return is valid, and raises a software
> exception if it cannot return.
> > Back To Top
> >
> > ---------------------------------
> >
> > How do I stop a forked thread? A forked block exits naturally. If you
> created the thread with one of the #fork messages, there is no need to
worry
> about exiting the thread. For example:
> > [ | a | 1000 timesRepeat: [ a := a + 1 ] ] fork
> > exits when it is done.
> > In Win32, the only general way to kill a thread is to use
> TerminateThread. This works on Smalltalk MT created threads as well, but
> leaves some Win32 resources open (refer to the Win32 documentation).
> > So, terminating a thread in an orderly fashion requires some
programming
> logic and synchronization. The Philosopher sample shows how to do this.
> > Back To Top
> >
> > ---------------------------------
> >
> > Getting Started with Projects...
> > A Windows Application requires at least the following components:
> >
> > source code in project format (.SP)
> > resources (in a DLL)
> > In order to open an application such as Generic, you must first
install
> the project file (generic.sp). The next step is to copy the resources into
> your path (i.e., copy generic.dll to your image directory). You can then
> open the application (look at the readme.txt file that comes with the
sample
> to see how to do this).
> > Some projects require additional components before they can be used.
The
> Project Browser will take care of it automatically (linking with DLLs and
> installing prerequisite projects).
> > Back To Top
> >
> > ---------------------------------
> >
> > Building an Executable You must first define a method
> ApplicationProcess>>winMain:with:with:with: that starts up your main
window
> (or whatever you want to do in the process). Define this method in a file
> called winmain.sm and place the file in the project directory.
> > The Project Browser checks for a winmain.sm file in the current
project
> directory before it enables the build EXE menu item.
> > You can use the Interface Builder to generate a squeleton application.
> In the Interface Builder, click on File|New... and select Resource Script.
> Choose a target directory and the elements to include in the application.
> > Back To Top
> >
> > ---------------------------------
> >
> > Debugging an Executable The generated executable raises an exception
at
> runtime:
>
------------------------------------------------------------------------
> ---
> > An instance of "Undefined Object" does not understand the
> > message "Symbol(16r1000ACA)". The message was sent
> > by an instance of "TestClient"
>
> --------------------------------------------------------------------------
> -
> > If you enable all error assertions you'll see the message box of the
> type "an instance of XXX did not understand Symbol(yyy), the message was
> sent by an instance of ZZZ".
> > In the development, evaluate
> > Symbol value: 16r1000ACA
> > and it displays the associated symbol string. You can also use the
Dump
> Viewer utility from the Transcript's toolbar.
> >
> > See also debugging for how to create a debugging version of a program.
> > Back To Top
> >
> > ---------------------------------
> >
> > Miscellaneous Memory Allocation Questions a) #basicAddress always
> returns an integer that is the object's address.
> > b) once you take an object's address, you must ensure that it is still
> referenced. The following is wrong:
> > | lf |
> > lf := LOGFONT new.
> > lf lfFaceName: 'Courier',' New'.
> > The reason is that 'Courier',' New' creates a new string which is
stored
> in a structure. The structure being a byte object, there are no more
> references to the string so it will be collected. Instead, use the code
> below instead:
> >
> > | lf szFont|
> > lf := LOGFONT new.
> > szFont := 'Courier',' New'.
> > lf lfFaceName: szFont.
> > self doSomethingWith: lf.
> > ^'and now szFont gets out of scope'
> > Note that the problem does not occur with literals (i.e., using
'Courier
> New') because literals are not collected by the garbage collector.
> > c) to be sure an object is not discarded, you can:
> > · -use #registerObject / #releaseObject
> > · allocate it on the external heap:
> > (String heapAlloc: szFont size) replaceFrom: 1 to: szFont size with:
> szFont; yourself
> > and free it using heapFree.
> > Back To Top
> >
> > ---------------------------------
> >
> > ApplicationProcess allInstances is empty ApplicationProcess is
> instantiated with the message #heapAlloc, which places it on the external
C
> heap. The method #allInstances only returns instances allocated on the
> Smalltalk heap. The method #allInstances also scans mapped memory regions.
> > Back To Top
> >
> > ---------------------------------
> >
> > Handling Window messages To process a window message such as
> WM_MOUSEMOVE, just implement a method named WM_XXX:with: (for a WM_XXX
> message). Don't forget to return a value as specified by the documentation
> of the message.
> > If the window that receives the message is a Windows control, the
method
> above will not directly work because the window procedure is implemented
by
> the control. First, check whether the control send notification events to
> its parent. In this case, install an event handler for the notification
> (using #when:in:perform:). Otherwise, create a Smalltalk subclass of the
> control that implements the windows message in question, and send it the
> message #subclassWindow upon creation. The TwinEdit sample on the
> distribution set demonstrates this.
> > Implementing WM_USER messages Non-standard messages can be handled in
> several ways:
> > · If the window is a dialog box, simply reimplement
> #wndProc:with:with:with: and test the msg parameter.
> > · A FrameWindow can reimplement #preTranslateMessage: or
> #defWindowProc:with:with:.
> > · Finally, it is also possible to add a new message map to
> WinMessagesEx. The key must be the message identifier and the value the
> selector to invoke in the receiver.
> > Back To Top
> >
> > ---------------------------------
> >
> > How to exit Smalltalk MT? To exit the development environment
> programmatically, evaluate:
> > Processor close
> > or
> > Processor close: aBlock
> > where aBlock is evaluated after the garbage collector has been
stopped.
> Use the second method if you must close a memory-mapped file.
> > Back To Top
> >
> > ---------------------------------
> >
> > MappedObjectStream only stores one object In Smalltalk MT, the
standard
> serialization methods use memory-mapping technology. MappedObjectStream
> implements an easy-to use interface. An instance of MappedObjectStream
maps
> a set of objects into the address space of the process. The top-level
object
> is called the root object. There is only one root object, but it can be
> arbitrary, and in particular it can be a collection.
> > If you open an existing file in RW mode, you can modify any object
that
> resides in the file. When the file is saved, external references are
> automatically appended to the end of the file. If you wish to add more
> objects, you can add them to the root collection or to any other object in
> the file.
> > Back To Top
> >
> > ---------------------------------
> >
> > Closing a memory-mapped file while keeping a reference generates an
> exception The default #close message does not nil out references.
Instead,
> use #unloadAndClose.
> > Note: The garbage collector (GC) scans all object references. If you
> close the mapped file while keeping a reference, an otherwise valid
> reference will suddenly point to nowhere. The GC algorithm assumes that an
> object reference is always valid. Otherwise, object traversal would be
much
> slower.
> > Back To Top
> >
> > ---------------------------------
> >
> > Saving an Image over the network
> > A Smalltalk image (development or runtime) can be started from a
network
> drive, with or without write permission. When the image is saved (which
> requires write permission), the new image receives the file creation date
of
> the remote system. If the system times of the two computers differ, it is
> possible that the new image files have an older timestamp than the
original
> files. This results in the new image files being overwritten when the
image
> is restarted via stmt.exe.
> > Possible workarounds are:
> > · Synchronize the clocks of the computers that are involved
> > · After saving, delete the old files stimage.exe and
sources.bin
> and start stmt.exe with the /nobackup option
> > Back To Top
> >
> > ---------------------------------
> >
> > Problems saving an image
> > Exceptions while saving an image are generally due to application data
> (either wanted or unwanted) in global, class or class instance variables.
If
> the data section of the image is not large enough to hold the data, an
> access violation occurs while serializing. The solutions are:
> > · If the data needs to be serialized with the image, augment
the
> size of the data section.
> > · Otherwise, implement a #serializeWith: method that cleans up
> the globally accessible variables.
> >
> > ---------------------------------
> >
> > Loading and unloading ActiveX Controls dynamically
> > It is possible to load and unload ActiveX controls at runtime. One
> benefit is that an application can delay loading an ActiveX control until
it
> is actually needed, which reduces the application startup time.
> > The following code fragment loads an ActiveX control (the Microsoft
Web
> Browser Control) dynamically. The application must first create an
> OleContainerWindow.
> > | oleContainer if |
> > oleContainer := self childAt: IDC_CONTROL1.
> > (if := IClassFactory coCreateInstance: (GUID IIDFromString:
> > '{8856F961-340A-11D0-A96B-00C04FD705A2}' )
> > interface: IUnknown) notNil ifTrue: [
> > oleContainer insertObject: if.
> > oleContainer invoke: 500 with: 'C:\\index.htm'.
> > ].
> >
> >
> > To unload the control:
> > oleContainer unload.
> >
> > Back To Top
> >
> > ---------------------------------
> >
> > Thread storage and blocks
> > Q:
> > I'm using the fork method to create multiple ST processes (i.e.,
Windows
> threads). It seems that the variables declared in the fork block are not
> thread-local:
> >
> > 1 to: 10 do: [ :i |
> > [ | id |
> > id := i.
> > ] fork
> > ]
> > A: The code fails for several reasons:
> > · First, the reference to i is a direct reference. So, by the
> time the assignment gets executed, i can hold anything. In particular, the
> method may even have exited.
> > · Secondly, only one block instance gets created and id is
> allocated in the home context, meaning that it is shared among threads
(note
> that the language compilation option <use automatic blocks> would allocate
> it on the stack).
> > You can define a TLS variable (Compiler addTlsSymbol:) to hold
> thread-specific data. This would create a different variable in each
thread,
> but it still doesn't solve the problem of assigning the correct value of
i.
> > Solution:
> > Implement a method that takes the variable i as argument:
> >
> > testFork: id
> > [ Processor outputDebugLine: id printString] fork
> > and run the loop as:
> > 1 to: 10 do: [ :i | self testFork: i]
> > Each method invocation creates a new block with its own copy of the
> arguments and the code executes as expected.
> > Back To Top
> >
> > ---------------------------------
> >
> > Transcript
> > Transcript is a thread-local variable, therefore you cannot access it
> from another thread. When you send a message to it from another thread
> (which assumes that you retrieved the Transcript object in the main thread
> and passed it through using a variable), Windows invokes the procedure in
> the main thread and blocks the calling thread until the Transcript
procedure
> returns. There are cases where this could cause a deadlock because of OLE
> synchronization.
> > For printing output, a much better solution is to use Processor
> outputDebugLine:[_with:]. The output goes to the debugging console, which
> can be an external debugger or DBMon. The method prints the image name and
> the thread id so you know which module and which thread writes the output.
> > Back To Top
> >
> >
> >
> >
> >
> > __________________________________________________
> > Correo Yahoo!
> > Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> > ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
>
>
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
On 2 Nov 2006 at 11:05, kikote gregoris wrote:
> Estaba tratando de cambiar el MethodDictionary de la clase para ver que pasaba
con las
> instancias, en VS no hay drama le coloque uno vacío y la instancia ya no
respondía a ningún
> mensaje y en el browser de clases los mensaje ya no existían.
> Me fui a MT para hacer lo mismo, tome el Core::ClassDescriptor de la clase le
coloque un
> StringDictionary vacío a una variable que conoce a los métodos.
> Luego fui a la instancia y le mande un mensaje, con el sorprendente resultado
de que me lo
> contesto sin ningún problema.
> Fui al browser y los mensajes no existían, recompile la clase para ver que
pasaba y nada la
> instancia seguía vivita y coleando respondiendo a los mensajes enviados.
No es tan sorprendente, sólo demuestra que la variable que vos tocaste no es un
MethoDictionary que se use en el method lookup como el de VS (aunque sí lo
usa el Browser).
> Luego me puse a ver como se hacían las llamadas a los métodos y encontré que
se hace de la
> siguiente forma.
[ . . . ]
> Además se puede llamar directamente a un método de la siguiente manera:
>
> MemoryManager call: (self methodAddressAt:#hola) receiver: self .
> Donde self es el objeto en cuestión.
Exactamente esta es la razón. Fijate que el MemoryManager es quién tiene la
responsabilidad de recordar dónde están los métodos asociados a los selectores
(esto es, resolver el method lookup). Y puede usar o no el diccionario de tu
descriptor. Probablemente no lo use, sino que tenga sus propias estructuras.
> Quería saber como se resuelven las llamadas a los métodos en VS y si tiene
algo de parecido con
> esto??.
¿Parecido con qué?
Podés hacer receiver perform: #hola, o podés tomar un CompiledMethod y
correrlo con un receiver. No sé si eso es lo que buscás.
La resolución de llamadas a métodos es trabajo de la máquina virtual.
> También me confunde el hecho de que al reemplazar el MethodDictionary por uno
vacío la
> instancia sigue respondiendo los mensajes que tenia definido, cosa que no pasa
en VS.
Porque resuelve el method lookup con otra cosa y no la que vos reemplazaste.
Saludos
--
Carlos E. Ferro
Caesar Systems
Estaba tratando de cambiar el MethodDictionary de la clase para ver que pasaba con las instancias, en VS no hay drama le coloque uno vacío y la instancia ya no respondía a ningún mensaje y en el browser de clases los mensaje ya no existían.
Me fui a MT para hacer lo mismo, tome el Core::ClassDescriptor de la clase le coloque un StringDictionary vacío a una variable que conoce a los
métodos.
Luego fui a la instancia y le mande un mensaje, con el sorprendente resultado de que me lo contesto sin ningún problema.
Fui al browser y los mensajes no existían, recompile la clase para ver que pasaba y nada la instancia seguía vivita y coleando respondiendo a los mensajes enviados.
Luego me puse a ver como se hacían las llamadas a los métodos y encontré que se hace de la siguiente forma.
self _try: [
result := MemoryManager call: methodVA
receiver: anObject.
Quería saber como se
resuelven las llamadas a los métodos en VS y si tiene algo de parecido con esto??.
También me confunde el hecho de que al reemplazar el MethodDictionary por uno vacío la instancia sigue respondiendo los mensajes que tenia definido, cosa que no pasa en VS.
Saludos kiko
__________________________________________________ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Me refería al hecho de si es posible sacar alguna conclusión sobre la validez o no de alguna de las 2 soluciones, si el caso que describo es muy habitual o no, y si debería preocuparme por que ocurra.
No trataba de comparar en velocidad a MT con VS solo se me ocurrió hacer esta
prueba y quise compartir los resultados.
Saludos kiko
"Alejandro F. Reimondo" <aleReimondo@...> escribió:
Hola kiko,
> Se pude sacar alguna conclusión de estos números??.
Cual sería la pregunta que estas tratando resolver? Que la motiva?
Lo digo porque no entiendo porque comparás MT con VS en velocidad, no encuentro un caso en dónde yo dudaría de usar uno u otro.
> No parece ser tan catastrófico usar #allInstances. No lo es. Pero es una de las cosas que uno debe tratar de evitar, si piensa que puede ser posible.
hasta
pronto, Ale.
----- Original Message ----- From: "kikote gregoris" <kikogregoris@...> To: <smalltalking@...> Sent: Tuesday, October 31, 2006 10:56 PM Subject: [objetos] Caso de Prueba en Cambio de instancias
> Hola Gente > > Estuve probando el peor caso para la implementación de VS. > Genere una colección de 1000 objetos y luego modifique su clase, luego la recorrí enviándole un mensaje a cada objeto para obligarlos a mutar. > Medí el tiempo que se tomo y tardo 13 segundos. > Luego implemente una versión trucha para MT donde para mutar uso #allInstances y realice algo parecido a lo de VS. > Tardo 3 segundos para 1000. > > Se pude sacar alguna conclusión de estos números??. > El ejemplo no incluye la generación de la colección solo la recorrida
y mutación. > No parece ser tan catastrófico usar #allInstances. > > Por ultimo tengo otra pregunta. > En VS la clase se recopila y listo, quiero decir que el St no pregunta si quiero recompilar, solo lo hace y punto. > En MT una clase no se recompila si uno no da la orden de que se haga, se que es una pregunta para hacerle a quien realizo el MT pero por hay tiene una sospecha de por que se hace esto. > > Saludos kiko > > PD: No se me ocurre una peor situación para probar en VS. > Copio algunas de las diferencias que tiene el MT sobre otros ST. > Aquí se destacan los beneficios de algunas de las diferencias. Si tienen tiempo de leer algo para opinar estaría buenísimo > > > Differences with other Smalltalk Dialects This section depicts the differences that
may exist with other Smalltalk dialects. In general, Smalltalk MT tries to follow existing implementation options for the sake of compatibility. > Compiler options allow you to increase the compatibility at the expense of code size and / or performance. > Pool Dictionaries reside in the sources In Smalltalk MT, Pool Dictionaries behave exactly like include files in C, i.e., they are part of the source base. Other Smalltalk implementations usually design pool dictionaries as global variables. In Smalltalk MT, a pool dictionary is not directly accessible from the image. You edit pool dictionaries by invoking the pool editor from the Options menu in the Class Hierarchy Browser. You can also load include files, and save a Smalltalk pool dictionary as an include file or as a Smalltalk chunk file. > Benefit: Reduced runtime requirements > > Symbols are not instances
of String In Smalltalk MT, a symbol is a byte object whose 32 bit value is an index into the symbol table. Because of this indirection, symbols are not unique (although their associated value is). The benefit of this approach is that the symbol table is not required during runtime, which substantially reduces the executable's size. > Optionally, Smalltalk MT can be configured to use identity symbols. > Benefit: Reduced runtime requirements > > Smalltalk is a class, not a dictionary In Smalltalk MT, the class Smalltalk takes over the functionality of the Smalltalk global variable present in most dialects. Smalltalk MT internally uses two dictionaries, SmalltalkGlobalDictionary for global variables, and SmalltalkClassDictionary for classes. Class Smalltalk implements also linking with an external Smalltalk DLL. > > Two types of global variables:
process-global and thread-local variables Smalltalk MT introduces thread local variables variables. Once declared, a thread-local variable exists in all threads, but its value is specific to each thread. > Global variables are visible from all threads. > > Metaclasses are created on demand A Metaclass is created on demand by sending the message #class to a class. > Benefit: Reduced storage requirements. > > Issues when adding methods to base classes In some cases, new methods cannot be installed directly in certain base classes, such as Array, LargeInteger, MappingTable, StringA. In these cases, the compiler saves the source code and emits a warning that the changes will not go into effect until the image is compressed. You must compress and restart the image to validate the modifications. > Note that this applies only to new methods
and under certain conditions; once installed, methods can be modified interactively. > > Simplified API Interface Before you can call an API, your image must be linked with the appropriate DLL. Once this is done, you can call an API with the keyword WINAPI. > Because objects never move in Smalltalk MT, you can directly pass objects as API arguments. Callbacks from non-Smalltalk code are also painless; any block can be passed as an API argument and called by non-Smalltalk code. Class methods can also be called, provided they belong to one of the Export categories. > Before an object is handed over to an API, it receives the hidden message #asCinteger. This message asks the receiving object for its 32 bit API representation. For example, a Window will answer the API representation of its handle. > Note: Smalltalk MT also supports dynamic binding, which loads a
DLL when needed at runtime. However, the programming interface is identical, which makes it easy to switch between the two modes. > > Local Variables are uninitialized (optional) For performance reasons, local variables in static contexts (method contexts without blocks) are uninitialized (like in C compilers). Using an uninitialized local variable generates a compilation error. However, an uninitialized state may go undetected accurately if conditional statements are used. > Note: You can enable and disable local variable initializations in the language properties. > > String Literals in methods are merged (optional) In order to save space, a literal string (or any other literal byte object) that occurs several times inside a method is only stored once. A side-effect is that an expression such as: > 'abc' == 'abc' > evaluates to
true. > > Literal Strings accept escape characters Literal strings can be specified using escape characters, introduced by '\'. The syntax is largely C-compliant. A consequence is that ordinary backslashes must be doubled. > > Other Differences in the Class Hierarchy File > Smalltalk MT has no actual File class. The functionality is taken over by FileStream. The identifier File is aliased to FileStream in order to support existing code. > A FileStream does not support some of the Stream methods that work at the byte granularity level. This would be inefficient because FileStream does not buffer I/O. MemoryStream should be used instead, because it takes advantage of the memory-mapped file system exposed by Win32. > > Dictionary Smalltalk MT uses MappingTable by default. Dictionary is aliased to MappingTable in order to
preserve existing code. > > Name aliasing The compiler accepts alternate identifiers for some classes. The alternate name lookup has the least precedence, so it doesn't interfere with existing classes. Installing a class that has an aliased name overrides the alias. > Example > By default, Dictionary is an alias for MappingTable. The extra Smalltalk project installs a class Dictionary that is defined as a Set of Associations (and therefore compatible with the original definition of Dictionary). Source code that references Dictionary will automatically refer to the new class when the project is installed, and to MappingTable when the project is removed. > > > Frequently Asked Questions Table of Contents > Deliverable Files > Questions about source code
strategy > What is the purpose of the message #_asCinteger ? > Is there a Notifier in Smalltalk MT? > What is the purpose of the window property 'STOBJ'? > ApplicationProcess allInstances is empty > I evaluated the following: [ ^self ] fork, and it raises an exception > Getting Started with Projects... > Building an Executable > Debugging an Executable > Miscellaneous Memory Allocation Questions > How do I stop a thread? > How do I exit Smalltalk MT by program? > MappedObjectStream only stores one object > Closing a memory-mapped file while keeping a reference generates exception > Saving an image over the network >
Problems saving an image > Sample Code: Loading and unloading ActiveX Controls dynamically > Thread storage and blocks > I cannot access Transcript from another thread > > --------------------------------- > > Deliverable Files What follows is a description of the files that you must or may ship with a Smalltalk MT executable: > File > Description > Status > strtdll25.DLL > runtime routines for ST/MT (15kB) > required > stsrl.DLL > serialization routines (60kB) > optional - used by memory-mapped files and object
serialization > stolestd.DLL > OLE helper library (44kB) > optional - used by some OLE / ActiveX classes > Back To Top > > --------------------------------- > > Source code strategy and naming conventions Class libraries > Smalltalk MT only implements classes / methods that are also used by the development environment or samples. That way, all source code has been tested. > Underscores > Underscores identify private messages, classes, or pseudo-messages (inlined messages). > Back To Top > > --------------------------------- > > What is the purpose of #_asCinteger? The message #_asCinteger is
sent implicitly to API arguments, and returns a 32 bit representation of an object. If the object cannot be passed to an API (for example nil), it raises an exception. > You can bypass this message with one of the messages #basicAddress, #_asInteger, or more generally with an inline message that returns a known type (such as #_longAtOffset:). > Note that the address manipulation methods (#atAddress:put: etc.) do not send the message, so you may have to send it yourself if the parameter is not an integer or LONG type. > Example: MemoryManager atAddress: ppEnumConnectionPoints put: ienum _asCinteger. > Back To Top > > --------------------------------- > > Does Smalltalk MT have a Notifier? Each window implements its own window procedure (although most windows inherit the default window procedure in Window), and exports it to
the operating system. > A Smalltalk-created window other than a dialog box reserves private data in its window creation structure, and stores the address of the Smalltalk object in that slot (remember: in ST/MT, objects are never moved). > A DialogBox functions exactly like a Dialog Box in C/C++ ; each instance has its own dialog procedure that references the Smalltalk object. > Back To Top > > --------------------------------- > > What is the purpose of the window property 'STOBJ' that is associated with a window? The purpose of this property is to be able to retrieve the Smalltalk object associated with a window, given the window handle. If the window is not maintained by Smalltalk (i.e., the window procedure is implemented elsewhere), the property will not be set. > Back To Top > >
--------------------------------- > > I evaluated the following: [ ^self ] fork, and it raises an exception The return statement in a block returns from the method that defines the block. If you create a thread that executes this block, the new thread would attempt to return from a method context in a parallel thread, therefore switching the stack and crashing. And your original thread would crash as well because the other thread corrupted its stack. Therefore, the code that actually returns verifies that the return is valid, and raises a software exception if it cannot return. > Back To Top > > --------------------------------- > > How do I stop a forked thread? A forked block exits naturally. If you created the thread with one of the #fork messages, there is no need to worry about exiting the thread. For example: > [ | a | 1000 timesRepeat: [ a
:= a + 1 ] ] fork > exits when it is done. > In Win32, the only general way to kill a thread is to use TerminateThread. This works on Smalltalk MT created threads as well, but leaves some Win32 resources open (refer to the Win32 documentation). > So, terminating a thread in an orderly fashion requires some programming logic and synchronization. The Philosopher sample shows how to do this. > Back To Top > > --------------------------------- > > Getting Started with Projects... > A Windows Application requires at least the following components: > > source code in project format (.SP) > resources (in a DLL) > In order to open an application such as Generic, you must first install the project file (generic.sp). The next step is to copy the resources into your path
(i.e., copy generic.dll to your image directory). You can then open the application (look at the readme.txt file that comes with the sample to see how to do this). > Some projects require additional components before they can be used. The Project Browser will take care of it automatically (linking with DLLs and installing prerequisite projects). > Back To Top > > --------------------------------- > > Building an Executable You must first define a method ApplicationProcess>>winMain:with:with:with: that starts up your main window (or whatever you want to do in the process). Define this method in a file called winmain.sm and place the file in the project directory. > The Project Browser checks for a winmain.sm file in the current project directory before it enables the build EXE menu item. > You can use the Interface Builder to
generate a squeleton application. In the Interface Builder, click on File|New... and select Resource Script. Choose a target directory and the elements to include in the application. > Back To Top > > --------------------------------- > > Debugging an Executable The generated executable raises an exception at runtime: > ------------------------------------------------------------------------ --- > An instance of "Undefined Object" does not understand the > message "Symbol(16r1000ACA)". The message was sent > by an instance of "TestClient" > -------------------------------------------------------------------------- - > If you enable all error assertions you'll see the message box of the type "an instance of XXX did not understand Symbol(yyy), the message was sent by an instance of ZZZ". > In the
development, evaluate > Symbol value: 16r1000ACA > and it displays the associated symbol string. You can also use the Dump Viewer utility from the Transcript's toolbar. > > See also debugging for how to create a debugging version of a program. > Back To Top > > --------------------------------- > > Miscellaneous Memory Allocation Questions a) #basicAddress always returns an integer that is the object's address. > b) once you take an object's address, you must ensure that it is still referenced. The following is wrong: > | lf | > lf := LOGFONT new. > lf lfFaceName: 'Courier',' New'. > The reason is that 'Courier',' New' creates a new string which is stored in a structure. The structure being a byte object, there are no more references to the string so
it will be collected. Instead, use the code below instead: > > | lf szFont| > lf := LOGFONT new. > szFont := 'Courier',' New'. > lf lfFaceName: szFont. > self doSomethingWith: lf. > ^'and now szFont gets out of scope' > Note that the problem does not occur with literals (i.e., using 'Courier New') because literals are not collected by the garbage collector. > c) to be sure an object is not discarded, you can: > · -use #registerObject / #releaseObject > · allocate it on the external heap: > (String heapAlloc: szFont size) replaceFrom: 1 to: szFont size with: szFont; yourself > and free it using heapFree. > Back To Top > >
--------------------------------- > > ApplicationProcess allInstances is empty ApplicationProcess is instantiated with the message #heapAlloc, which places it on the external C heap. The method #allInstances only returns instances allocated on the Smalltalk heap. The method #allInstances also scans mapped memory regions. > Back To Top > > --------------------------------- > > Handling Window messages To process a window message such as WM_MOUSEMOVE, just implement a method named WM_XXX:with: (for a WM_XXX message). Don't forget to return a value as specified by the documentation of the message. > If the window that receives the message is a Windows control, the method above will not directly work because the window procedure is implemented by the control. First, check whether the control send notification events to its parent. In this case,
install an event handler for the notification (using #when:in:perform:). Otherwise, create a Smalltalk subclass of the control that implements the windows message in question, and send it the message #subclassWindow upon creation. The TwinEdit sample on the distribution set demonstrates this. > Implementing WM_USER messages Non-standard messages can be handled in several ways: > · If the window is a dialog box, simply reimplement #wndProc:with:with:with: and test the msg parameter. > · A FrameWindow can reimplement #preTranslateMessage: or #defWindowProc:with:with:. > · Finally, it is also possible to add a new message map to WinMessagesEx. The key must be the message identifier and the value the selector to invoke in the
receiver. > Back To Top > > --------------------------------- > > How to exit Smalltalk MT? To exit the development environment programmatically, evaluate: > Processor close > or > Processor close: aBlock > where aBlock is evaluated after the garbage collector has been stopped. Use the second method if you must close a memory-mapped file. > Back To Top > > --------------------------------- > > MappedObjectStream only stores one object In Smalltalk MT, the standard serialization methods use memory-mapping technology. MappedObjectStream implements an easy-to use interface. An instance of MappedObjectStream maps a set of objects into the address space of the process. The top-level object is called the root object. There is only one root object, but it can
be arbitrary, and in particular it can be a collection. > If you open an existing file in RW mode, you can modify any object that resides in the file. When the file is saved, external references are automatically appended to the end of the file. If you wish to add more objects, you can add them to the root collection or to any other object in the file. > Back To Top > > --------------------------------- > > Closing a memory-mapped file while keeping a reference generates an exception The default #close message does not nil out references. Instead, use #unloadAndClose. > Note: The garbage collector (GC) scans all object references. If you close the mapped file while keeping a reference, an otherwise valid reference will suddenly point to nowhere. The GC algorithm assumes that an object reference is always valid. Otherwise, object traversal would be
much slower. > Back To Top > > --------------------------------- > > Saving an Image over the network > A Smalltalk image (development or runtime) can be started from a network drive, with or without write permission. When the image is saved (which requires write permission), the new image receives the file creation date of the remote system. If the system times of the two computers differ, it is possible that the new image files have an older timestamp than the original files. This results in the new image files being overwritten when the image is restarted via stmt.exe. > Possible workarounds are: > · Synchronize the clocks of the computers that are involved > · After saving, delete the old files stimage.exe and sources.bin and start
stmt.exe with the /nobackup option > Back To Top > > --------------------------------- > > Problems saving an image > Exceptions while saving an image are generally due to application data (either wanted or unwanted) in global, class or class instance variables. If the data section of the image is not large enough to hold the data, an access violation occurs while serializing. The solutions are: > · If the data needs to be serialized with the image, augment the size of the data section. > · Otherwise, implement a #serializeWith: method that cleans up the globally accessible variables. > > --------------------------------- > > Loading and unloading ActiveX Controls dynamically > It is possible to load and unload
ActiveX controls at runtime. One benefit is that an application can delay loading an ActiveX control until it is actually needed, which reduces the application startup time. > The following code fragment loads an ActiveX control (the Microsoft Web Browser Control) dynamically. The application must first create an OleContainerWindow. > | oleContainer if | > oleContainer := self childAt: IDC_CONTROL1. > (if := IClassFactory coCreateInstance: (GUID IIDFromString: > '{8856F961-340A-11D0-A96B-00C04FD705A2}' ) > interface: IUnknown) notNil ifTrue: [ > oleContainer insertObject: if. > oleContainer invoke: 500 with: 'C:\\index.htm'. > ]. > > > To unload the control: >
oleContainer unload. > > Back To Top > > --------------------------------- > > Thread storage and blocks > Q: > I'm using the fork method to create multiple ST processes (i.e., Windows threads). It seems that the variables declared in the fork block are not thread-local: > > 1 to: 10 do: [ :i | > [ | id | > id := i. > ] fork > ] > A: The code fails for several reasons: > · First, the reference to i is a direct reference. So, by the time the assignment gets executed, i can hold anything. In particular, the method may even have exited. > · Secondly, only one block instance gets created and id
is allocated in the home context, meaning that it is shared among threads (note that the language compilation option <use automatic blocks> would allocate it on the stack). > You can define a TLS variable (Compiler addTlsSymbol:) to hold thread-specific data. This would create a different variable in each thread, but it still doesn't solve the problem of assigning the correct value of i. > Solution: > Implement a method that takes the variable i as argument: > > testFork: id > [ Processor outputDebugLine: id printString] fork > and run the loop as: > 1 to: 10 do: [ :i | self testFork: i] > Each method invocation creates a new block with its own copy of the arguments and the code executes as expected. > Back To Top > >
--------------------------------- > > Transcript > Transcript is a thread-local variable, therefore you cannot access it from another thread. When you send a message to it from another thread (which assumes that you retrieved the Transcript object in the main thread and passed it through using a variable), Windows invokes the procedure in the main thread and blocks the calling thread until the Transcript procedure returns. There are cases where this could cause a deadlock because of OLE synchronization. > For printing output, a much better solution is to use Processor outputDebugLine:[_with:]. The output goes to the debugging console, which can be an external debugger or DBMon. The method prints the image name and the thread id so you know which module and which thread writes the output. > Back To Top > > > > > >
__________________________________________________ > Correo Yahoo! > Espacio para todos tus mensajes, antivirus y antispam ¡gratis! > ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
__________________________________________________ Correo Yahoo! Espacio para todos tus mensajes, antivirus y antispam ¡gratis! ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
Hola kiko,
> Se pude sacar alguna conclusión de estos números??.
Cual sería la pregunta que estas tratando resolver?
Que la motiva?
Lo digo porque no entiendo porque comparás
MT con VS en velocidad, no encuentro un caso
en dónde yo dudaría de usar uno u otro.
> No parece ser tan catastrófico usar #allInstances.
No lo es.
Pero es una de las cosas que uno debe tratar de evitar,
si piensa que puede ser posible.
hasta pronto,
Ale.
----- Original Message -----
From: "kikote gregoris" <kikogregoris@...>
To: <smalltalking@...>
Sent: Tuesday, October 31, 2006 10:56 PM
Subject: [objetos] Caso de Prueba en Cambio de instancias
> Hola Gente
>
> Estuve probando el peor caso para la implementación de VS.
> Genere una colección de 1000 objetos y luego modifique su clase, luego
la recorrí enviándole un mensaje a cada objeto para obligarlos a mutar.
> Medí el tiempo que se tomo y tardo 13 segundos.
> Luego implemente una versión trucha para MT donde para mutar uso
#allInstances y realice algo parecido a lo de VS.
> Tardo 3 segundos para 1000.
>
> Se pude sacar alguna conclusión de estos números??.
> El ejemplo no incluye la generación de la colección solo la recorrida y
mutación.
> No parece ser tan catastrófico usar #allInstances.
>
> Por ultimo tengo otra pregunta.
> En VS la clase se recopila y listo, quiero decir que el St no pregunta
si quiero recompilar, solo lo hace y punto.
> En MT una clase no se recompila si uno no da la orden de que se haga, se
que es una pregunta para hacerle a quien realizo el MT pero por hay tiene
una sospecha de por que se hace esto.
>
> Saludos kiko
>
> PD: No se me ocurre una peor situación para probar en VS.
> Copio algunas de las diferencias que tiene el MT sobre otros ST.
> Aquí se destacan los beneficios de algunas de las diferencias. Si tienen
tiempo de leer algo para opinar estaría buenísimo
>
>
> Differences with other Smalltalk Dialects This section depicts the
differences that may exist with other Smalltalk dialects. In general,
Smalltalk MT tries to follow existing implementation options for the sake of
compatibility.
> Compiler options allow you to increase the compatibility at the expense
of code size and / or performance.
> Pool Dictionaries reside in the sources In Smalltalk MT, Pool
Dictionaries behave exactly like include files in C, i.e., they are part of
the source base. Other Smalltalk implementations usually design pool
dictionaries as global variables. In Smalltalk MT, a pool dictionary is not
directly accessible from the image. You edit pool dictionaries by invoking
the pool editor from the Options menu in the Class Hierarchy Browser. You
can also load include files, and save a Smalltalk pool dictionary as an
include file or as a Smalltalk chunk file.
> Benefit: Reduced runtime requirements
>
> Symbols are not instances of String In Smalltalk MT, a symbol is a byte
object whose 32 bit value is an index into the symbol table. Because of this
indirection, symbols are not unique (although their associated value is).
The benefit of this approach is that the symbol table is not required during
runtime, which substantially reduces the executable's size.
> Optionally, Smalltalk MT can be configured to use identity symbols.
> Benefit: Reduced runtime requirements
>
> Smalltalk is a class, not a dictionary In Smalltalk MT, the class
Smalltalk takes over the functionality of the Smalltalk global variable
present in most dialects. Smalltalk MT internally uses two dictionaries,
SmalltalkGlobalDictionary for global variables, and SmalltalkClassDictionary
for classes. Class Smalltalk implements also linking with an external
Smalltalk DLL.
>
> Two types of global variables: process-global and thread-local variables
Smalltalk MT introduces thread local variables variables. Once declared, a
thread-local variable exists in all threads, but its value is specific to
each thread.
> Global variables are visible from all threads.
>
> Metaclasses are created on demand A Metaclass is created on demand by
sending the message #class to a class.
> Benefit: Reduced storage requirements.
>
> Issues when adding methods to base classes In some cases, new methods
cannot be installed directly in certain base classes, such as Array,
LargeInteger, MappingTable, StringA. In these cases, the compiler saves the
source code and emits a warning that the changes will not go into effect
until the image is compressed. You must compress and restart the image to
validate the modifications.
> Note that this applies only to new methods and under certain conditions;
once installed, methods can be modified interactively.
>
> Simplified API Interface Before you can call an API, your image must be
linked with the appropriate DLL. Once this is done, you can call an API with
the keyword WINAPI.
> Because objects never move in Smalltalk MT, you can directly pass
objects as API arguments. Callbacks from non-Smalltalk code are also
painless; any block can be passed as an API argument and called by
non-Smalltalk code. Class methods can also be called, provided they belong
to one of the Export categories.
> Before an object is handed over to an API, it receives the hidden
message #asCinteger. This message asks the receiving object for its 32 bit
API representation. For example, a Window will answer the API representation
of its handle.
> Note: Smalltalk MT also supports dynamic binding, which loads a DLL when
needed at runtime. However, the programming interface is identical, which
makes it easy to switch between the two modes.
>
> Local Variables are uninitialized (optional) For performance reasons,
local variables in static contexts (method contexts without blocks) are
uninitialized (like in C compilers). Using an uninitialized local variable
generates a compilation error. However, an uninitialized state may go
undetected accurately if conditional statements are used.
> Note: You can enable and disable local variable initializations in the
language properties.
>
> String Literals in methods are merged (optional) In order to save
space, a literal string (or any other literal byte object) that occurs
several times inside a method is only stored once. A side-effect is that an
expression such as:
> 'abc' == 'abc'
> evaluates to true.
>
> Literal Strings accept escape characters Literal strings can be
specified using escape characters, introduced by '\'. The syntax is largely
C-compliant. A consequence is that ordinary backslashes must be doubled.
>
> Other Differences in the Class Hierarchy File
> Smalltalk MT has no actual File class. The functionality is taken over
by FileStream. The identifier File is aliased to FileStream in order to
support existing code.
> A FileStream does not support some of the Stream methods that work at
the byte granularity level. This would be inefficient because FileStream
does not buffer I/O. MemoryStream should be used instead, because it takes
advantage of the memory-mapped file system exposed by Win32.
>
> Dictionary Smalltalk MT uses MappingTable by default. Dictionary is
aliased to MappingTable in order to preserve existing code.
>
> Name aliasing The compiler accepts alternate identifiers for some
classes. The alternate name lookup has the least precedence, so it doesn't
interfere with existing classes. Installing a class that has an aliased name
overrides the alias.
> Example
> By default, Dictionary is an alias for MappingTable. The extra Smalltalk
project installs a class Dictionary that is defined as a Set of Associations
(and therefore compatible with the original definition of Dictionary).
Source code that references Dictionary will automatically refer to the new
class when the project is installed, and to MappingTable when the project is
removed.
>
>
> Frequently Asked Questions Table of Contents
> Deliverable Files
> Questions about source code strategy
> What is the purpose of the message #_asCinteger ?
> Is there a Notifier in Smalltalk MT?
> What is the purpose of the window property 'STOBJ'?
> ApplicationProcess allInstances is empty
> I evaluated the following: [ ^self ] fork, and it raises an exception
> Getting Started with Projects...
> Building an Executable
> Debugging an Executable
> Miscellaneous Memory Allocation Questions
> How do I stop a thread?
> How do I exit Smalltalk MT by program?
> MappedObjectStream only stores one object
> Closing a memory-mapped file while keeping a reference generates
exception
> Saving an image over the network
> Problems saving an image
> Sample Code: Loading and unloading ActiveX Controls dynamically
> Thread storage and blocks
> I cannot access Transcript from another thread
>
> ---------------------------------
>
> Deliverable Files What follows is a description of the files that you
must or may ship with a Smalltalk MT executable:
> File
> Description
> Status
> strtdll25.DLL
> runtime routines for ST/MT (15kB)
> required
> stsrl.DLL
> serialization routines (60kB)
> optional - used by memory-mapped files and object serialization
> stolestd.DLL
> OLE helper library (44kB)
> optional - used by some OLE / ActiveX classes
> Back To Top
>
> ---------------------------------
>
> Source code strategy and naming conventions Class libraries
> Smalltalk MT only implements classes / methods that are also used by
the development environment or samples. That way, all source code has been
tested.
> Underscores
> Underscores identify private messages, classes, or pseudo-messages
(inlined messages).
> Back To Top
>
> ---------------------------------
>
> What is the purpose of #_asCinteger? The message #_asCinteger is sent
implicitly to API arguments, and returns a 32 bit representation of an
object. If the object cannot be passed to an API (for example nil), it
raises an exception.
> You can bypass this message with one of the messages #basicAddress,
#_asInteger, or more generally with an inline message that returns a known
type (such as #_longAtOffset:).
> Note that the address manipulation methods (#atAddress:put: etc.) do not
send the message, so you may have to send it yourself if the parameter is
not an integer or LONG type.
> Example: MemoryManager atAddress: ppEnumConnectionPoints put: ienum
_asCinteger.
> Back To Top
>
> ---------------------------------
>
> Does Smalltalk MT have a Notifier? Each window implements its own
window procedure (although most windows inherit the default window procedure
in Window), and exports it to the operating system.
> A Smalltalk-created window other than a dialog box reserves private data
in its window creation structure, and stores the address of the Smalltalk
object in that slot (remember: in ST/MT, objects are never moved).
> A DialogBox functions exactly like a Dialog Box in C/C++ ; each instance
has its own dialog procedure that references the Smalltalk object.
> Back To Top
>
> ---------------------------------
>
> What is the purpose of the window property 'STOBJ' that is associated
with a window? The purpose of this property is to be able to retrieve the
Smalltalk object associated with a window, given the window handle. If the
window is not maintained by Smalltalk (i.e., the window procedure is
implemented elsewhere), the property will not be set.
> Back To Top
>
> ---------------------------------
>
> I evaluated the following: [ ^self ] fork, and it raises an exception
The return statement in a block returns from the method that defines the
block. If you create a thread that executes this block, the new thread would
attempt to return from a method context in a parallel thread, therefore
switching the stack and crashing. And your original thread would crash as
well because the other thread corrupted its stack. Therefore, the code that
actually returns verifies that the return is valid, and raises a software
exception if it cannot return.
> Back To Top
>
> ---------------------------------
>
> How do I stop a forked thread? A forked block exits naturally. If you
created the thread with one of the #fork messages, there is no need to worry
about exiting the thread. For example:
> [ | a | 1000 timesRepeat: [ a := a + 1 ] ] fork
> exits when it is done.
> In Win32, the only general way to kill a thread is to use
TerminateThread. This works on Smalltalk MT created threads as well, but
leaves some Win32 resources open (refer to the Win32 documentation).
> So, terminating a thread in an orderly fashion requires some programming
logic and synchronization. The Philosopher sample shows how to do this.
> Back To Top
>
> ---------------------------------
>
> Getting Started with Projects...
> A Windows Application requires at least the following components:
>
> source code in project format (.SP)
> resources (in a DLL)
> In order to open an application such as Generic, you must first install
the project file (generic.sp). The next step is to copy the resources into
your path (i.e., copy generic.dll to your image directory). You can then
open the application (look at the readme.txt file that comes with the sample
to see how to do this).
> Some projects require additional components before they can be used. The
Project Browser will take care of it automatically (linking with DLLs and
installing prerequisite projects).
> Back To Top
>
> ---------------------------------
>
> Building an Executable You must first define a method
ApplicationProcess>>winMain:with:with:with: that starts up your main window
(or whatever you want to do in the process). Define this method in a file
called winmain.sm and place the file in the project directory.
> The Project Browser checks for a winmain.sm file in the current project
directory before it enables the build EXE menu item.
> You can use the Interface Builder to generate a squeleton application.
In the Interface Builder, click on File|New... and select Resource Script.
Choose a target directory and the elements to include in the application.
> Back To Top
>
> ---------------------------------
>
> Debugging an Executable The generated executable raises an exception at
runtime:
> ------------------------------------------------------------------------
---
> An instance of "Undefined Object" does not understand the
> message "Symbol(16r1000ACA)". The message was sent
> by an instance of "TestClient"
> --------------------------------------------------------------------------
-
> If you enable all error assertions you'll see the message box of the
type "an instance of XXX did not understand Symbol(yyy), the message was
sent by an instance of ZZZ".
> In the development, evaluate
> Symbol value: 16r1000ACA
> and it displays the associated symbol string. You can also use the Dump
Viewer utility from the Transcript's toolbar.
>
> See also debugging for how to create a debugging version of a program.
> Back To Top
>
> ---------------------------------
>
> Miscellaneous Memory Allocation Questions a) #basicAddress always
returns an integer that is the object's address.
> b) once you take an object's address, you must ensure that it is still
referenced. The following is wrong:
> | lf |
> lf := LOGFONT new.
> lf lfFaceName: 'Courier',' New'.
> The reason is that 'Courier',' New' creates a new string which is stored
in a structure. The structure being a byte object, there are no more
references to the string so it will be collected. Instead, use the code
below instead:
>
> | lf szFont|
> lf := LOGFONT new.
> szFont := 'Courier',' New'.
> lf lfFaceName: szFont.
> self doSomethingWith: lf.
> ^'and now szFont gets out of scope'
> Note that the problem does not occur with literals (i.e., using 'Courier
New') because literals are not collected by the garbage collector.
> c) to be sure an object is not discarded, you can:
> · -use #registerObject / #releaseObject
> · allocate it on the external heap:
> (String heapAlloc: szFont size) replaceFrom: 1 to: szFont size with:
szFont; yourself
> and free it using heapFree.
> Back To Top
>
> ---------------------------------
>
> ApplicationProcess allInstances is empty ApplicationProcess is
instantiated with the message #heapAlloc, which places it on the external C
heap. The method #allInstances only returns instances allocated on the
Smalltalk heap. The method #allInstances also scans mapped memory regions.
> Back To Top
>
> ---------------------------------
>
> Handling Window messages To process a window message such as
WM_MOUSEMOVE, just implement a method named WM_XXX:with: (for a WM_XXX
message). Don't forget to return a value as specified by the documentation
of the message.
> If the window that receives the message is a Windows control, the method
above will not directly work because the window procedure is implemented by
the control. First, check whether the control send notification events to
its parent. In this case, install an event handler for the notification
(using #when:in:perform:). Otherwise, create a Smalltalk subclass of the
control that implements the windows message in question, and send it the
message #subclassWindow upon creation. The TwinEdit sample on the
distribution set demonstrates this.
> Implementing WM_USER messages Non-standard messages can be handled in
several ways:
> · If the window is a dialog box, simply reimplement
#wndProc:with:with:with: and test the msg parameter.
> · A FrameWindow can reimplement #preTranslateMessage: or
#defWindowProc:with:with:.
> · Finally, it is also possible to add a new message map to
WinMessagesEx. The key must be the message identifier and the value the
selector to invoke in the receiver.
> Back To Top
>
> ---------------------------------
>
> How to exit Smalltalk MT? To exit the development environment
programmatically, evaluate:
> Processor close
> or
> Processor close: aBlock
> where aBlock is evaluated after the garbage collector has been stopped.
Use the second method if you must close a memory-mapped file.
> Back To Top
>
> ---------------------------------
>
> MappedObjectStream only stores one object In Smalltalk MT, the standard
serialization methods use memory-mapping technology. MappedObjectStream
implements an easy-to use interface. An instance of MappedObjectStream maps
a set of objects into the address space of the process. The top-level object
is called the root object. There is only one root object, but it can be
arbitrary, and in particular it can be a collection.
> If you open an existing file in RW mode, you can modify any object that
resides in the file. When the file is saved, external references are
automatically appended to the end of the file. If you wish to add more
objects, you can add them to the root collection or to any other object in
the file.
> Back To Top
>
> ---------------------------------
>
> Closing a memory-mapped file while keeping a reference generates an
exception The default #close message does not nil out references. Instead,
use #unloadAndClose.
> Note: The garbage collector (GC) scans all object references. If you
close the mapped file while keeping a reference, an otherwise valid
reference will suddenly point to nowhere. The GC algorithm assumes that an
object reference is always valid. Otherwise, object traversal would be much
slower.
> Back To Top
>
> ---------------------------------
>
> Saving an Image over the network
> A Smalltalk image (development or runtime) can be started from a network
drive, with or without write permission. When the image is saved (which
requires write permission), the new image receives the file creation date of
the remote system. If the system times of the two computers differ, it is
possible that the new image files have an older timestamp than the original
files. This results in the new image files being overwritten when the image
is restarted via stmt.exe.
> Possible workarounds are:
> · Synchronize the clocks of the computers that are involved
> · After saving, delete the old files stimage.exe and sources.bin
and start stmt.exe with the /nobackup option
> Back To Top
>
> ---------------------------------
>
> Problems saving an image
> Exceptions while saving an image are generally due to application data
(either wanted or unwanted) in global, class or class instance variables. If
the data section of the image is not large enough to hold the data, an
access violation occurs while serializing. The solutions are:
> · If the data needs to be serialized with the image, augment the
size of the data section.
> · Otherwise, implement a #serializeWith: method that cleans up
the globally accessible variables.
>
> ---------------------------------
>
> Loading and unloading ActiveX Controls dynamically
> It is possible to load and unload ActiveX controls at runtime. One
benefit is that an application can delay loading an ActiveX control until it
is actually needed, which reduces the application startup time.
> The following code fragment loads an ActiveX control (the Microsoft Web
Browser Control) dynamically. The application must first create an
OleContainerWindow.
> | oleContainer if |
> oleContainer := self childAt: IDC_CONTROL1.
> (if := IClassFactory coCreateInstance: (GUID IIDFromString:
> '{8856F961-340A-11D0-A96B-00C04FD705A2}' )
> interface: IUnknown) notNil ifTrue: [
> oleContainer insertObject: if.
> oleContainer invoke: 500 with: 'C:\\index.htm'.
> ].
>
>
> To unload the control:
> oleContainer unload.
>
> Back To Top
>
> ---------------------------------
>
> Thread storage and blocks
> Q:
> I'm using the fork method to create multiple ST processes (i.e., Windows
threads). It seems that the variables declared in the fork block are not
thread-local:
>
> 1 to: 10 do: [ :i |
> [ | id |
> id := i.
> ] fork
> ]
> A: The code fails for several reasons:
> · First, the reference to i is a direct reference. So, by the
time the assignment gets executed, i can hold anything. In particular, the
method may even have exited.
> · Secondly, only one block instance gets created and id is
allocated in the home context, meaning that it is shared among threads (note
that the language compilation option <use automatic blocks> would allocate
it on the stack).
> You can define a TLS variable (Compiler addTlsSymbol:) to hold
thread-specific data. This would create a different variable in each thread,
but it still doesn't solve the problem of assigning the correct value of i.
> Solution:
> Implement a method that takes the variable i as argument:
>
> testFork: id
> [ Processor outputDebugLine: id printString] fork
> and run the loop as:
> 1 to: 10 do: [ :i | self testFork: i]
> Each method invocation creates a new block with its own copy of the
arguments and the code executes as expected.
> Back To Top
>
> ---------------------------------
>
> Transcript
> Transcript is a thread-local variable, therefore you cannot access it
from another thread. When you send a message to it from another thread
(which assumes that you retrieved the Transcript object in the main thread
and passed it through using a variable), Windows invokes the procedure in
the main thread and blocks the calling thread until the Transcript procedure
returns. There are cases where this could cause a deadlock because of OLE
synchronization.
> For printing output, a much better solution is to use Processor
outputDebugLine:[_with:]. The output goes to the debugging console, which
can be an external debugger or DBMon. The method prints the image name and
the thread id so you know which module and which thread writes the output.
> Back To Top
>
>
>
>
>
> __________________________________________________
> Correo Yahoo!
> Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
> ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar