Originally at 2014-12-19T20:31:05Z by Herbert Vojčík
EDIT: From 0.14.1, there is API for what is proposed here, Smalltalk optOut: foo sets klass of foo to null without leaking the abstraction.
This thing is open to debate. In Amber core, there is now support for tagging specific instances of JavaScript objects that are wrapped by Amber (arrays, functions, dates etc.) with
foo.allowJavaScriptCalls = true;
If object is tagged with this, it is treated as normal wrapped Smalltalk object (an Array, a BlockClosure, a Date etc.) and in case of DNU, it is treated as plain, nonwrapped JS object (foo bar: 1 baz: 2 is translated to foo.bar(1,2)). There is one object, which is by default tagged as this: jQuery - jQuery is a function, so a BlockClosure in Amber, but thanks to allowJavaScriptCalls it possible to call eg. jQuery.ajax(...) directly as jQuery ajax: ... and: ... and: ..., though it still plays as a BlockClosure instance, reverting to JS proxying on DNU).
This kind of treatment is only needed for instances of wrapped classes. Non-wrapped JS object is treated fine via JSObjectProxy on its own.
Now, there is another, simpler way how to strip an object its Smalltalkiness and leave it as if it was a plain non-wrapped JS object:
foo.klass = null;
(or, from 0.14.1 use the builtin API Smalltalk optOut: foo)
What this does is for foo object is that it literally takes away its Smalltalk nature (as it is examined by klass being non-null) and thus it is treated as a plain JS object (wrapped in JSObjectProxy wherever it plays the receiver). This also means it is not treated any more as a wrapped class instance, so a JS function tagged this way is no more instance of BlockClosure so you cannot do foo value: 3 to do foo(3).
Drawing from jQuery example, it is actually never used as a Smalltalk BlockClosure. Every use of jQuery in Smalltalk code is a jQuery ajax: ...-like use, and in a few places where jQuery needs to be called as a function, <js-code> method is used anyway. So it seems, the latter form of tagging could actually be used, but it is matter of debate.
Pros of .klass=null I see are: more compact kernel code (it needs no support to work, it works out of the box and allowJavaScriptCalls support can be removed) and explicit marking an object as "JS" object.
Cons of .klass=null I see are: inability to use an object in its wrapped form (no ability to call value: for a function and size for an array). REMOVED: "and possible abstraction leak (klass is actually where Smalltalk class is stored, instances inheriting it from JS prototype chain)" since there is an API for that: Smalltalk optOut: foo.
Reactions welcome (and feedback of other users of allowJavaScriptCalls = true if klass = null works for them).
Originally at 2014-12-19T20:31:05Z by Herbert Vojčík
EDIT: From 0.14.1, there is API for what is proposed here, `Smalltalk optOut: foo` sets `klass` of `foo` to `null` without leaking the abstraction.
This thing is open to debate. In Amber core, there is now support for tagging specific instances of JavaScript objects that are wrapped by Amber (arrays, functions, dates etc.) with
```js
foo.allowJavaScriptCalls = true;
```
If object is tagged with this, it is treated as normal wrapped Smalltalk object (an Array, a BlockClosure, a Date etc.) and in case of DNU, it is treated as plain, nonwrapped JS object (`foo bar: 1 baz: 2` is translated to `foo.bar(1,2)`). There is one object, which is by default tagged as this: jQuery - jQuery is a function, so a BlockClosure in Amber, but thanks to `allowJavaScriptCalls` it possible to call eg. `jQuery.ajax(...)` directly as `jQuery ajax: ... and: ... and: ...`, though it still plays as a BlockClosure instance, reverting to JS proxying on DNU).
This kind of treatment is only needed for instances of wrapped classes. Non-wrapped JS object is treated fine via `JSObjectProxy` on its own.
Now, there is another, simpler way how to strip an object its Smalltalkiness and leave it as if it was a plain non-wrapped JS object:
```js
foo.klass = null;
```
(or, from 0.14.1 use the builtin API `Smalltalk optOut: foo`)
What this does is for `foo` object is that it literally takes away its Smalltalk nature (as it is examined by `klass` being non-null) and thus it is treated as a plain JS object (wrapped in `JSObjectProxy` wherever it plays the receiver). This also means it is not treated any more as a wrapped class instance, so a JS function tagged this way is no more instance of BlockClosure so you cannot do `foo value: 3` to do `foo(3)`.
Drawing from jQuery example, it is actually _never_ used as a Smalltalk BlockClosure. Every use of `jQuery` in Smalltalk code is a `jQuery ajax: ...`-like use, and in a few places where `jQuery` needs to be called as a function, `<js-code>` method is used anyway. So it seems, the latter form of tagging could actually be used, but it is matter of debate.
Pros of `.klass=null` I see are: more compact kernel code (it needs no support to work, it works out of the box and `allowJavaScriptCalls` support can be removed) and explicit marking an object as "JS" object.
Cons of `.klass=null` I see are: inability to use an object in its wrapped form (no ability to call `value:` for a function and `size` for an array). REMOVED: "and possible abstraction leak (`klass` is actually where Smalltalk class is stored, instances inheriting it from JS prototype chain)" since there is an API for that: `Smalltalk optOut: foo`.
Reactions welcome (and feedback of other users of `allowJavaScriptCalls = true` if `klass = null` works for them).
<bountysource-plugin>
---
Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/7145060-change-allowjavascript-true-with-klass-null?utm_campaign=plugin&utm_content=tracker%2F79201&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F79201&utm_medium=issues&utm_source=github).
</bountysource-plugin>
Originally at 2014-12-19T20:31:05Z by Herbert Vojčík
EDIT: From 0.14.1, there is API for what is proposed here,
Smalltalk optOut: foo
setsklass
offoo
tonull
without leaking the abstraction.This thing is open to debate. In Amber core, there is now support for tagging specific instances of JavaScript objects that are wrapped by Amber (arrays, functions, dates etc.) with
If object is tagged with this, it is treated as normal wrapped Smalltalk object (an Array, a BlockClosure, a Date etc.) and in case of DNU, it is treated as plain, nonwrapped JS object (
foo bar: 1 baz: 2
is translated tofoo.bar(1,2)
). There is one object, which is by default tagged as this: jQuery - jQuery is a function, so a BlockClosure in Amber, but thanks toallowJavaScriptCalls
it possible to call eg.jQuery.ajax(...)
directly asjQuery ajax: ... and: ... and: ...
, though it still plays as a BlockClosure instance, reverting to JS proxying on DNU).This kind of treatment is only needed for instances of wrapped classes. Non-wrapped JS object is treated fine via
JSObjectProxy
on its own.Now, there is another, simpler way how to strip an object its Smalltalkiness and leave it as if it was a plain non-wrapped JS object:
(or, from 0.14.1 use the builtin API
Smalltalk optOut: foo
)What this does is for
foo
object is that it literally takes away its Smalltalk nature (as it is examined byklass
being non-null) and thus it is treated as a plain JS object (wrapped inJSObjectProxy
wherever it plays the receiver). This also means it is not treated any more as a wrapped class instance, so a JS function tagged this way is no more instance of BlockClosure so you cannot dofoo value: 3
to dofoo(3)
.Drawing from jQuery example, it is actually never used as a Smalltalk BlockClosure. Every use of
jQuery
in Smalltalk code is ajQuery ajax: ...
-like use, and in a few places wherejQuery
needs to be called as a function,<js-code>
method is used anyway. So it seems, the latter form of tagging could actually be used, but it is matter of debate.Pros of
.klass=null
I see are: more compact kernel code (it needs no support to work, it works out of the box andallowJavaScriptCalls
support can be removed) and explicit marking an object as "JS" object. Cons of.klass=null
I see are: inability to use an object in its wrapped form (no ability to callvalue:
for a function andsize
for an array). REMOVED: "and possible abstraction leak (klass
is actually where Smalltalk class is stored, instances inheriting it from JS prototype chain)" since there is an API for that:Smalltalk optOut: foo
.Reactions welcome (and feedback of other users of
allowJavaScriptCalls = true
ifklass = null
works for them).Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Both are still present in kernel, though the former is not used in any official piece of code (jQuery wrapper uses the latter).
.allowJavaScriptCalls
removed,.klass=null
performed bySmalltalk optOut: anObject
.