Inline JavaScript and Amber translation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Inline JavaScript and Amber translation

horrido
I successfully (and easily!) integrated the D3.js library into my welcome application. However, in trying to test it out, I've encountered an odd situation...

First of all, I have this in my index.html:

<svg width="720" height="120">
 
<circle cx="40" cy="60" r="10"></circle>
 
<circle cx="80" cy="60" r="10"></circle>
 
<circle cx="120" cy="60" r="10"></circle>
</svg>

Then I have this method:

foo
   
<
   
var circle = d3.selectAll("circle");
    circle
.style("fill", "steelblue");
    circle
.attr("r", 30);
   
>

This works perfectly. Now, to translate it into Amber:

bar
   
| circle |
    circle
:= d3 selectAll: 'circle'.
   
circle style: 'fill' set: 'steelblue'.
   
circle attr: 'r' set: 30.

This fails miserably because #circle is a nil object! Upon inspection, it shows as 'an Array (an Array ([object SVGCircleElement] [object SVGCircleElement] [object SVGCircleElement]))'. What the hell???

Just for a laugh, I tried this:

bar
   
| circle |
    circle
:= d3 selectAll: 'circle'.
   
((circle at: 1) at: 1) style: 'fill' set: 'steelblue'.
   
((circle at: 1) at: 1) attr: 'r' set: 30.

But it says: "[object SVGCircleElement] does not understand #attr:set:". And if I comment out the last line, leaving only style: 'fill' set: 'steelblue', it doesn't work–the colour doesn't change.

Anyway, I don't know what's going on. Why isn't my straight translation into Amber correct? The inline JavaScript is certainly correct.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Inline JavaScript and Amber translation

Herby Vojčík


Richard Eng wrote:

> I successfully (and easily!) integrated the D3.js library into my
> welcome application. However, in trying to test it out, I've encountered
> an odd situation...
>
> First of all, I have this in my index.html:
>
> ||
> <svgwidth="720"height="120">
> <circlecx="40"cy="60"r="10"></circle>
> <circlecx="80"cy="60"r="10"></circle>
> <circlecx="120"cy="60"r="10"></circle>
> </svg>
>
> Then I have this method:
>
> ||
> foo
> <
> varcircle =d3.selectAll("circle");
> circle.style("fill","steelblue");
> circle.attr("r",30);
>>
>
> This works perfectly. Now, to translate it into Amber:
>
> ||
> bar
> |circle |
> circle :=d3 selectAll:'circle'.
> circlestyle:'fill'set:'steelblue'.
> circleattr:'r'set:30.
>
> This fails miserably because #circle is a nil object! Upon inspection,
> it shows as 'an Array (an Array ([object SVGCircleElement] [object

How can it be nil object if it shows Array upon inspection? It cannot be
both at the same time!

> SVGCircleElement] [object SVGCircleElement]))'. What the hell???

Anyway, the problem here is not with bad translation, it is because it
is a (JS) Array. Some JS classes are wrapped by Amber classes and thus
are not JS objects any more, but they are now instance of Amber classes.

If you do either

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Forcing treatment as JS object"
   (JSObjectProxy on: circle) style: 'fill' set: 'steelblue'.
   (JSObjectProxy on: circle) attr: 'r' set: 30.

or

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Strip the wrapping, return to state of JS object"
   Smalltalk optOut: circle.
   circle style: 'fill' set: 'steelblue'.
   circle attr: 'r' set: 30.

The latter is preferred, and it can maybe even be automatized (d3 object
are not arrays per se, but only inherit the Array via some intermediate,
like d3.fn.prototype or so, I presume (where would they have .style or
.attr methods from)? It is enough to smalltalk optout on that object,
and then, magically, all of d3 objects will be JS object for Amber, not
wrapped as Array instances; you may try it by running this method first:

optOutD3
<
   // 'circle' is not important, this is just to get to the prototype
   var proto = d3.selectAll('circle').__proto__;
   $globals.Smalltalk._optOut_(proto);
 >

Maybe after running this, you sanitize d3 and then you previous method
will just work, without changes.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Inline JavaScript and Amber translation

horrido
Bad choice of words. I meant the value is nil; it's not a nil object.


On Tuesday, 9 June 2015 09:38:36 UTC-4, Herby wrote:


Richard Eng wrote:

> I successfully (and easily!) integrated the D3.js library into my
> welcome application. However, in trying to test it out, I've encountered
> an odd situation...
>
> First of all, I have this in my index.html:
>
> ||
> <svgwidth="720"height="120">
> <circlecx="40"cy="60"r="10"></circle>
> <circlecx="80"cy="60"r="10"></circle>
> <circlecx="120"cy="60"r="10"></circle>
> </svg>
>
> Then I have this method:
>
> ||
> foo
> <
> varcircle =d3.selectAll("circle");
> circle.style("fill","steelblue");
> circle.attr("r",30);
>>
>
> This works perfectly. Now, to translate it into Amber:
>
> ||
> bar
> |circle |
> circle :=d3 selectAll:'circle'.
> circlestyle:'fill'set:'steelblue'.
> circleattr:'r'set:30.
>
> This fails miserably because #circle is a nil object! Upon inspection,
> it shows as 'an Array (an Array ([object SVGCircleElement] [object

How can it be nil object if it shows Array upon inspection? It cannot be
both at the same time!

> SVGCircleElement] [object SVGCircleElement]))'. What the hell???

Anyway, the problem here is not with bad translation, it is because it
is a (JS) Array. Some JS classes are wrapped by Amber classes and thus
are not JS objects any more, but they are now instance of Amber classes.

If you do either

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Forcing treatment as JS object"
   (JSObjectProxy on: circle) style: 'fill' set: 'steelblue'.
   (JSObjectProxy on: circle) attr: 'r' set: 30.

or

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Strip the wrapping, return to state of JS object"
   Smalltalk optOut: circle.
   circle style: 'fill' set: 'steelblue'.
   circle attr: 'r' set: 30.

The latter is preferred, and it can maybe even be automatized (d3 object
are not arrays per se, but only inherit the Array via some intermediate,
like d3.fn.prototype or so, I presume (where would they have .style or
.attr methods from)? It is enough to smalltalk optout on that object,
and then, magically, all of d3 objects will be JS object for Amber, not
wrapped as Array instances; you may try it by running this method first:

optOutD3
<
   // 'circle' is not important, this is just to get to the prototype
   var proto = d3.selectAll('circle').__proto__;
   $globals.Smalltalk._optOut_(proto);
 >

Maybe after running this, you sanitize d3 and then you previous method
will just work, without changes.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Inline JavaScript and Amber translation

Herby Vojčík


Richard Eng wrote:
> Bad choice of words. I meant the value is nil; it's not a nil object.

Even then, if inspection shows it is an array, it cannot have value nil.
What do you mean by 'valur is nil' anyway? One of the rough definitions
of value may be "what inspector presents you", which definitely is not
nil. Other, much less rough is, "what console shows when you run
`console dir: self` in inspector window or `console dir: anObject` in
workspace. Even then, it will not present you with null, undefined or
SmalltalkNil instance, I would presume.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Inline JavaScript and Amber translation

horrido
In reply to this post by Herby Vojčík
Some JS classes are wrapped by Amber classes and thus are not JS objects any more, but they are now instance of Amber classes.
 
Maybe after running this, you sanitize d3...

This adds quite a wrinkle to using external libraries. Now, you have to understand exactly what kind of objects the library is returning to you. Not that d3js.org tells you up front. So you need to play around or do some debugging before finally completing your integration. Yuck!


On Tuesday, 9 June 2015 09:38:36 UTC-4, Herby wrote:


Richard Eng wrote:

> I successfully (and easily!) integrated the D3.js library into my
> welcome application. However, in trying to test it out, I've encountered
> an odd situation...
>
> First of all, I have this in my index.html:
>
> ||
> <svgwidth="720"height="120">
> <circlecx="40"cy="60"r="10"></circle>
> <circlecx="80"cy="60"r="10"></circle>
> <circlecx="120"cy="60"r="10"></circle>
> </svg>
>
> Then I have this method:
>
> ||
> foo
> <
> varcircle =d3.selectAll("circle");
> circle.style("fill","steelblue");
> circle.attr("r",30);
>>
>
> This works perfectly. Now, to translate it into Amber:
>
> ||
> bar
> |circle |
> circle :=d3 selectAll:'circle'.
> circlestyle:'fill'set:'steelblue'.
> circleattr:'r'set:30.
>
> This fails miserably because #circle is a nil object! Upon inspection,
> it shows as 'an Array (an Array ([object SVGCircleElement] [object

How can it be nil object if it shows Array upon inspection? It cannot be
both at the same time!

> SVGCircleElement] [object SVGCircleElement]))'. What the hell???

Anyway, the problem here is not with bad translation, it is because it
is a (JS) Array. Some JS classes are wrapped by Amber classes and thus
are not JS objects any more, but they are now instance of Amber classes.

If you do either

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Forcing treatment as JS object"
   (JSObjectProxy on: circle) style: 'fill' set: 'steelblue'.
   (JSObjectProxy on: circle) attr: 'r' set: 30.

or

   bar
   | circle |
   circle :=d3 selectAll:'circle'.
   "Strip the wrapping, return to state of JS object"
   Smalltalk optOut: circle.
   circle style: 'fill' set: 'steelblue'.
   circle attr: 'r' set: 30.

The latter is preferred, and it can maybe even be automatized (d3 object
are not arrays per se, but only inherit the Array via some intermediate,
like d3.fn.prototype or so, I presume (where would they have .style or
.attr methods from)? It is enough to smalltalk optout on that object,
and then, magically, all of d3 objects will be JS object for Amber, not
wrapped as Array instances; you may try it by running this method first:

optOutD3
<
   // 'circle' is not important, this is just to get to the prototype
   var proto = d3.selectAll('circle').__proto__;
   $globals.Smalltalk._optOut_(proto);
 >

Maybe after running this, you sanitize d3 and then you previous method
will just work, without changes.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Inline JavaScript and Amber translation

Herby Vojčík


Richard Eng wrote:

>     Some JS classes are wrapped by Amber classes and thus are not JS
>     objects any more, but they are now instance of Amber classes.
>
>     Maybe after running this, you sanitize d3...
>
>
> This adds quite a wrinkle to using external libraries. Now, you have to
> understand exactly what kind of objects the library is returning to you.
> Not that d3js.org tells you up front. So you need to play around or do
> some debugging before finally completing your integration. Yuck!

"Yuck!" only because they sort-of monkey patch the builtin Array, you know.

There's no additional burden for well-behaving ones.

If you want to know which classes are wrapped, `Smalltalk core
wrappedClasses` should give you list of them.

>
>
> On Tuesday, 9 June 2015 09:38:36 UTC-4, Herby wrote:
>
>
>
>     Richard Eng wrote:
>      > I successfully (and easily!) integrated the D3.js library into my
>      > welcome application. However, in trying to test it out, I've
>     encountered
>      > an odd situation...
>      >
>      > First of all, I have this in my index.html:
>      >
>      > ||
>      > <svgwidth="720"height="120">
>      > <circlecx="40"cy="60"r="10"></circle>
>      > <circlecx="80"cy="60"r="10"></circle>
>      > <circlecx="120"cy="60"r="10"></circle>
>      > </svg>
>      >
>      > Then I have this method:
>      >
>      > ||
>      > foo
>      > <
>      > varcircle =d3.selectAll("circle");
>      > circle.style("fill","steelblue");
>      > circle.attr("r",30);
>      >>
>      >
>      > This works perfectly. Now, to translate it into Amber:
>      >
>      > ||
>      > bar
>      > |circle |
>      > circle :=d3 selectAll:'circle'.
>      > circlestyle:'fill'set:'steelblue'.
>      > circleattr:'r'set:30.
>      >
>      > This fails miserably because #circle is a nil object! Upon
>     inspection,
>      > it shows as 'an Array (an Array ([object SVGCircleElement] [object
>
>     How can it be nil object if it shows Array upon inspection? It
>     cannot be
>     both at the same time!
>
>      > SVGCircleElement] [object SVGCircleElement]))'. What the hell???
>
>     Anyway, the problem here is not with bad translation, it is because it
>     is a (JS) Array. Some JS classes are wrapped by Amber classes and thus
>     are not JS objects any more, but they are now instance of Amber
>     classes.
>
>     If you do either
>
>     bar
>     | circle |
>     circle :=d3 selectAll:'circle'.
>     "Forcing treatment as JS object"
>     (JSObjectProxy on: circle) style: 'fill' set: 'steelblue'.
>     (JSObjectProxy on: circle) attr: 'r' set: 30.
>
>     or
>
>     bar
>     | circle |
>     circle :=d3 selectAll:'circle'.
>     "Strip the wrapping, return to state of JS object"
>     Smalltalk optOut: circle.
>     circle style: 'fill' set: 'steelblue'.
>     circle attr: 'r' set: 30.
>
>     The latter is preferred, and it can maybe even be automatized (d3
>     object
>     are not arrays per se, but only inherit the Array via some
>     intermediate,
>     like d3.fn.prototype or so, I presume (where would they have .style or
>     .attr methods from)? It is enough to smalltalk optout on that object,
>     and then, magically, all of d3 objects will be JS object for Amber, not
>     wrapped as Array instances; you may try it by running this method
>     first:
>
>     optOutD3
>     <
>     // 'circle' is not important, this is just to get to the prototype
>     var proto = d3.selectAll('circle').__proto__;
>     $globals.Smalltalk._optOut_(proto);
>      >
>
>     Maybe after running this, you sanitize d3 and then you previous method
>     will just work, without changes.
>
> --
> You received this message because you are subscribed to the Google
> Groups "amber-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email]
> <mailto:[hidden email]>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.