These are chat archives for opal/opal

17th
May 2018
Mitch VanDuyn
@catmando
May 17 2018 18:01
does anybody know about method JS.call(...)
I can't seem to track down where or how it gets defined!
Jan Biedermann
@janbiedermann
May 17 2018 18:06
JS.call is from opal
JS.call(this_arg, args_as_array)
i believe
its not defined as such, its just "bridged" to js
so with JS.call you call the javascript call
JS being the opal bridge to JS
so in opal function_name.JS.call(this_or_that, *args) or something
Ilya Bylich
@iliabylich
May 17 2018 18:11
@catmando It's not a method actually. Opal converts recv.JS.prop to recv['property'] in the DotJsSyntax rewriter - https://github.com/opal/opal/blob/master/lib/opal/rewriters/dot_js_syntax.rb
So for example you can get window.global_variable using
`window`.JS.global_variable
(I'm a bit wrong, .JS.f becomes .f(), .JS[:f] becomes just .f)
Mitch VanDuyn
@catmando
May 17 2018 18:15
huh
in the JS console I see Opal.JS.$call is defined
Ilya Bylich
@iliabylich
May 17 2018 18:15
That's a special syntax
To make it working you need to compile it
It doesn't work "as is" in the JS console

in the JS console I see Opal.JS.$call is defined

Opal has a JS module and $call most probably is a method missing stub

Mitch VanDuyn
@catmando
May 17 2018 18:17
Opal.JS.$call('eval', 'window')
returns the window
huh... but not in try-opal
so I am guessing hyperloop defines it someplace
Jan Biedermann
@janbiedermann
May 17 2018 18:19
huh
Mitch VanDuyn
@catmando
May 17 2018 18:21
but I can't find it.
@iliabylich what I need at any rate is a method like JS.eval('my js string')
I can't use back ticks or %x{...} to drop into JS, for complicated reasons...
do you know of any method that does this?
eiko
@eiko
May 17 2018 18:24
by any chance would other delimiters work for you? like %x-...- and %x(...) are all valid
Mitch VanDuyn
@catmando
May 17 2018 18:27
no the problem is that hyper-spec allows you to write your rspecs and include chunks of opal code in a ruby block. hyper-spec then get the source tree for the block and recompiles it using opal, and then runs it.
so if I say this:
expect_evaluate_ruby do
  Element[`document`]
end.to eq...
it does not work since the decompiler process breaks on the back ticks for whatever reason.
so elsewhere I have used JS.call(:eval, 'document')
but I can't find where the heck this JS.call thing got defined :-)
Jan Biedermann
@janbiedermann
May 17 2018 18:30
why are you looking for it? Why does the last version call(:eval) not work for you now? Or what are you trying to do?
Mitch VanDuyn
@catmando
May 17 2018 18:32
yeah I am writing specs using hyper-spec without any other hyper-loop stuff. So the magic JS.call must be defined someplace in hyperloop but I can't find it.
and it should be defined in hyper-spec, but I want to make sure that I don't overwrite the definition and screw up something else.
Jan Biedermann
@janbiedermann
May 17 2018 18:36
.JS.call is here lib/opal/rewriters/dot_js_syntax.rb
and JS is here stdlib/js.rb
at the bottom you find your .call
there
also you may have a look at hyper-react specs, maybe that problem you have is solved there somewhere already
Mitch VanDuyn
@catmando
May 17 2018 18:40
so perhaps js.rb is not included in stdlib unless you require it explicitly?
or maybe... stdlib is not being required by this gem I am testing...
Jan Biedermann
@janbiedermann
May 17 2018 18:41
this may be correct
should throw, but JS module is also here:
opal/corelib/error.rb
so thats why JS as module is known, but the method .call is not
eiko
@eiko
May 17 2018 19:11
I'm looking into why Element[`document`] didn't work in the first place, and I think it's a bug somewhere which can be resolved.
Jan Biedermann
@janbiedermann
May 17 2018 19:13
Element[document] gets unparsed by unparser, thats why it fails
eiko
@eiko
May 17 2018 19:15

it gets unparsed to

`#{"document"}`

which, as weird as the syntax is, should be considered functionally synonymous to

`document`
Jan Biedermann
@janbiedermann
May 17 2018 20:18
@iliabylich @elia how can i prepend something before opening after compilation is done?
in top.rb https://github.com/opal/opal/blob/2c2093cff2694fe949faeda79dce84d9b7f2a33d/lib/opal/nodes/top.rb#L18
?
eiko
@eiko
May 17 2018 20:24
doesn't that code already prepend opening to anything compiled?
Jan Biedermann
@janbiedermann
May 17 2018 20:25
yes, maybe i expressed myself in a unclear way, i want to insert something before opening
i think i got it, i mess with @fragments directly, which is just a array
Jan Biedermann
@janbiedermann
May 17 2018 20:38
there actually is a unshift in base.rb
eiko
@eiko
May 17 2018 21:28
@catmando I submitted an issue on Unparse to see if they'll fix it. If not, it may be possible to hack hyper-spec itself
at the moment I'm working on a really gross monkeypatch:
def escape_jsxstr source
  source.gsub(/^(?<start>.*)`(?<contents>.+)`(?<end>.*)$/, '\k<start>\'!JSXSTR!\k<contents>!JSXSTR!\'\k<end>')
end

def unescape_jsxstr source
  source.gsub(/[',"]!JSXSTR!/, "`").gsub(/!JSXSTR![',"]/, "`")
end
it basically replaces `` with normal strings before parsing, then reverts them after the parse
Mitch VanDuyn
@catmando
May 17 2018 21:47
hohoho
Ilya Bylich
@iliabylich
May 17 2018 22:07
@janbiedermann If you need this behavior for every file that gets compiled by opal you could use rewriters. But I'm not sure if it's a good idea, rewriters are global and if you add a custom rewriter and someone else adds one more they may conflict
If you are going to use them, please note that the :top node is virtual, we create it in the compiler, so you won't see it in the rewriter
so the following thing may work for you: your custom rewriter may have a single method process(node) that prepends some AST into this node and simply returns a result
Ilya Bylich
@iliabylich
May 17 2018 22:12
rewriters are not documented btw, I'm not even sure that we need to expose this API, so if you need any guidance feel free to ask me

@eiko What's the issue with the backticks?

`#{"echo 1"}`

works fine for me

And it's absolutely equivalent to
`echo 1`
Jan Biedermann
@janbiedermann
May 17 2018 23:06
thx @iliabylich good to know :+1: , gives me some ideas