Hi guys I'm on holidays (no book no mooc no bugs just playing magic good music and hacking a bit) and I wanted to implemented a fun object that learn from Object by copying the methods. ProtoObject subclass: #ATMinimalLearningObject instanceVariableNames: '' classVariableNames: '' package: 'MiniActalk2' ATMinimalLearningObject >> doesNotUnderstand: aMessage | sel | sel := aMessage selector. Transcript show: 'Does not understand ', sel printString ; cr. ^ (Object includesSelector: sel) ifTrue: [ self addFromObjectSelector: sel. aMessage sendTo: self ] ifFalse: [ super doesNotUnderstand: aMessage ]. ATMinimalLearningObject >> addFromObjectSelector: aSelector | method | method := OpalCompiler new class: self class; source: (Object sourceCodeAt: aSelector); compile. self class addSelector: aSelector withMethod: method. ATMinimalLearningObject subclass: #ATProtozoid instanceVariableNames: 'ff' classVariableNames: '' package: 'MiniActalk2' Now it is working but I have the impression that we may have a problem. When I do ATProtozoid new instVarAt: 1 I get the following definition for instVarAt: instVarAt: t1 self error: 'Decompilation failed' but Object sourceCodeAt: #instVarAt: returns the correct string. 'instVarAt: index "Primitive. Answer a fixed variable in an object. The numbering of the variables corresponds to the named instance variables, followed by the indexed instance variables. Fail if the index is not an Integer or is not the index of a fixed variable. Essential. See Object documentation whatIsAPrimitive." <primitive: 173 error: ec> self primitiveFailed' May be the compile is not logging the method body. But since the compiler is full uncommented this is super nice to learn and get empowered. Stef
Hello, The logging of sources is not part of the compiler. It is part of the behavior API. Something like that would work : ATMinimalLearningObject >> addFromObjectSelector: aSelector self class compile: (Object >> aSelector) sourceCode classified: #foo Now it is strange that the decompiler can't decompile instVarAt: . It looks like it is a bug related to primitive error code decompilation. This is something I should look at during the sprint... 2016-01-27 20:42 GMT+01:00 stepharo <stepharo@free.fr>:
Hi guys
I'm on holidays (no book no mooc no bugs just playing magic good music and hacking a bit) and I wanted to implemented a fun object that learn from Object by copying the methods.
ProtoObject subclass: #ATMinimalLearningObject instanceVariableNames: '' classVariableNames: '' package: 'MiniActalk2'
ATMinimalLearningObject >> doesNotUnderstand: aMessage
| sel | sel := aMessage selector. Transcript show: 'Does not understand ', sel printString ; cr. ^ (Object includesSelector: sel) ifTrue: [ self addFromObjectSelector: sel. aMessage sendTo: self ] ifFalse: [ super doesNotUnderstand: aMessage ].
ATMinimalLearningObject >> addFromObjectSelector: aSelector
| method | method := OpalCompiler new class: self class; source: (Object sourceCodeAt: aSelector); compile. self class addSelector: aSelector withMethod: method.
ATMinimalLearningObject subclass: #ATProtozoid instanceVariableNames: 'ff' classVariableNames: '' package: 'MiniActalk2'
Now it is working but I have the impression that we may have a problem.
When I do ATProtozoid new instVarAt: 1
I get the following definition for instVarAt:
instVarAt: t1 self error: 'Decompilation failed'
but
Object sourceCodeAt: #instVarAt: returns the correct string.
'instVarAt: index "Primitive. Answer a fixed variable in an object. The numbering of the variables corresponds to the named instance variables, followed by the indexed instance variables. Fail if the index is not an Integer or is not the index of a fixed variable. Essential. See Object documentation whatIsAPrimitive."
<primitive: 173 error: ec> self primitiveFailed'
May be the compile is not logging the method body. But since the compiler is full uncommented this is super nice to learn and get empowered.
Stef
I wanted to avoid to use the class Api becuase with ProtoObject you never know. I think that I found the problem. The compilation happens in another thread. Le 28/1/16 00:17, Clément Bera a écrit :
Hello,
The logging of sources is not part of the compiler. It is part of the behavior API.
Something like that would work :
ATMinimalLearningObject >> addFromObjectSelector: aSelector self class compile: (Object >> aSelector) sourceCode classified: #foo
Now it is strange that the decompiler can't decompile instVarAt: . It looks like it is a bug related to primitive error code decompilation. This is something I should look at during the sprint...
2016-01-27 20:42 GMT+01:00 stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>:
Hi guys
I'm on holidays (no book no mooc no bugs just playing magic good music and hacking a bit) and I wanted to implemented a fun object that learn from Object by copying the methods.
ProtoObject subclass: #ATMinimalLearningObject instanceVariableNames: '' classVariableNames: '' package: 'MiniActalk2'
ATMinimalLearningObject >> doesNotUnderstand: aMessage
| sel | sel := aMessage selector. Transcript show: 'Does not understand ', sel printString ; cr. ^ (Object includesSelector: sel) ifTrue: [ self addFromObjectSelector: sel. aMessage sendTo: self ] ifFalse: [ super doesNotUnderstand: aMessage ].
ATMinimalLearningObject >> addFromObjectSelector: aSelector
| method | method := OpalCompiler new class: self class; source: (Object sourceCodeAt: aSelector); compile. self class addSelector: aSelector withMethod: method.
ATMinimalLearningObject subclass: #ATProtozoid instanceVariableNames: 'ff' classVariableNames: '' package: 'MiniActalk2'
Now it is working but I have the impression that we may have a problem.
When I do ATProtozoid new instVarAt: 1
I get the following definition for instVarAt:
instVarAt: t1 self error: 'Decompilation failed'
but
Object sourceCodeAt: #instVarAt: returns the correct string.
'instVarAt: index "Primitive. Answer a fixed variable in an object. The numbering of the variables corresponds to the named instance variables, followed by the indexed instance variables. Fail if the index is not an Integer or is not the index of a fixed variable. Essential. See Object documentation whatIsAPrimitive."
<primitive: 173 error: ec> self primitiveFailed'
May be the compile is not logging the method body. But since the compiler is full uncommented this is super nice to learn and get empowered.
Stef
2016-01-28 8:23 GMT+01:00 stepharo <stepharo@free.fr>:
I wanted to avoid to use the class Api becuase with ProtoObject you never know. I think that I found the problem. The compilation happens in another thread.
It is strange. You create new compiler instance for each method. How they can influence each other?
- You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class. - Maybe it is writing to the sources file that doesnât work from different processes?
On 28 ene 2016, at 9:53 a.m., Denis Kudriashov <dionisiydk@gmail.com> wrote:
2016-01-28 8:23 GMT+01:00 stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>: I wanted to avoid to use the class Api becuase with ProtoObject you never know. I think that I found the problem. The compilation happens in another thread.
It is strange. You create new compiler instance for each method. How they can influence each other?
2016-01-28 10:43 GMT+01:00 Guillermo Polito <guillermopolito@gmail.com>:
- You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class.
But is not #addSelector:withMethod: should take care about it? I guess traits installation not creates methods by compiling.
- Maybe it is writing to the sources file that doesnât work from different processes?
It should be fixed by synchronising such operations. Anyway copy approach should not touch source file at all.
On 28 ene 2016, at 11:07 a.m., Denis Kudriashov <dionisiydk@gmail.com> wrote:
2016-01-28 10:43 GMT+01:00 Guillermo Polito <guillermopolito@gmail.com <mailto:guillermopolito@gmail.com>>: - You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class.
But is not #addSelector:withMethod: should take care about it? I guess traits installation not creates methods by compiling.
For traits. But I wouldnât be sure for others :). This is a part of the system that need some love I think...
- Maybe it is writing to the sources file that doesnât work from different processes?
It should be fixed by synchronising such operations. Anyway copy approach should not touch source file at all.
Le 28/1/16 09:53, Denis Kudriashov a écrit :
2016-01-28 8:23 GMT+01:00 stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>:
I wanted to avoid to use the class Api becuase with ProtoObject you never know. I think that I found the problem. The compilation happens in another thread.
It is strange. You create new compiler instance for each method. How they can influence each other?
No idea :) May be this is a problem between the compiler and the source access.
Hi. Nice trick :) 2016-01-27 20:42 GMT+01:00 stepharo <stepharo@free.fr>:
ATMinimalLearningObject >> addFromObjectSelector: aSelector
| method | method := OpalCompiler new class: self class; source: (Object sourceCodeAt: aSelector); compile. self class addSelector: aSelector withMethod: method.
Why compilation is needed? Is adding copy of method not working? self class addSelector: aSelector withMethod: (Object >> aSelector) copy.
Indeed I could but I thought that recompiling I was sure that everything is correct Le 28/1/16 09:51, Denis Kudriashov a écrit :
Hi.
Nice trick :)
2016-01-27 20:42 GMT+01:00 stepharo <stepharo@free.fr <mailto:stepharo@free.fr>>:
ATMinimalLearningObject >> addFromObjectSelector: aSelector
| method | method := OpalCompiler new class: self class; source: (Object sourceCodeAt: aSelector); compile. self class addSelector: aSelector withMethod: method.
Why compilation is needed? Is adding copy of method not working?
self class addSelector: aSelector withMethod: (Object >> aSelector) copy.
participants (4)
-
Clément Bera -
Denis Kudriashov -
Guillermo Polito -
stepharo