#1116 change `.allowJavaScript = true` with `.klass = null`

Closed
opened 8 years ago by nero · 2 comments

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).

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

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>
Herby Vojčík commented 7 years ago
Owner

Both are still present in kernel, though the former is not used in any official piece of code (jQuery wrapper uses the latter).

Both are still present in kernel, though the former is not used in any official piece of code (jQuery wrapper uses the latter).
Herby Vojčík commented 6 years ago
Owner

.allowJavaScriptCalls removed, .klass=null performed by Smalltalk optOut: anObject.

`.allowJavaScriptCalls` removed, `.klass=null` performed by `Smalltalk optOut: anObject`.
Sign in to join this conversation.
No Label
No Milestone
No assignee
2 Participants
Loading...
Cancel
Save
There is no content yet.