Fork me on GitHub
#sci
<
2023-06-08
>
Sam Ritchie18:06:06

@borkdude or anyone — I am working on a portal viewer that’s cljs evaluated via sci. this require fails with “could not find namespace: goog.object” https://github.com/mentat-collective/Leva.cljs/blob/main/src/leva/schema.cljs#L6 is there a replacement I can use, for goog.object/set with a string key (not known at compile time) and value?

Sam Ritchie18:06:21

I would use assoc if I were in cljs, but I’m mutating a JS object here

borkdude18:06:11

yes, (aset obj "foo" "bar")

Sam Ritchie18:06:07

okay nice, whenever I do that someone pops up and says “only use aset with arrays!!”

borkdude18:06:21

yeah, I know ;P

borkdude 2
Sam Ritchie18:06:12

borkdude approved, done! and yes this is clearly the right way, thanks!

borkdude18:06:59

cljs.user=> (doto #js {} (js/Reflect.set "foo" "bar"))
#js {:foo "bar"}

borkdude18:06:14

but this is way more expensive in SCI, so I'd just use aset

Sam Ritchie21:06:19

@borkdude any preferred substitute for this-as in sci?

borkdude21:06:03

depends on the exact example

Sam Ritchie21:06:39

this is from portal, when I try to require a cljs file that uses this-as inside of it cc @U1G869VNV

Sam Ritchie21:06:00

@borkdude oh whoops I assumed your link was a docstring for this-as, instead it’s a workaround -

borkdude21:06:06

yes, this-as is only possible in a compiled language, in an interpreter I haven't found a way

Sam Ritchie21:06:06

there must be some other way to get the “context” for the event, I’ll read up

Sam Ritchie21:06:40

I think I can get around this

djblue21:06:45

thisAs = new Function('return this'); var obj = { fn: thisAs }; obj.fn()
=> {fn: ƒ}

borkdude21:06:34

nice :)

user=> (def thisAs (new js/Function "return this"))
#'user/thisAs
user=> (def obj #js {:fn thisAs})
#'user/obj
user=> (.fn obj)
#js {:fn #object[anonymous]}

borkdude21:06:38

(this is SCI)

borkdude21:06:37

I guess I could use that in SCI and track where the this-as local is used and insert a call to this special thisAs function instead

borkdude21:06:43

another alternative would be to wrap every function body in SCI with this-as in the host, but not sure if there would be a performance impact

djblue21:06:03

Although, I guess this-as is a macros

(defmacro this-as
  "Defines a scope where JavaScript's implit this is bound to the name provided."
  [name & body]
  `(let [~name (~'js* "this")]
     ~@body))

borkdude21:06:28

in CLJS it's a macro, but in SCI I could treat it as a special thing

👍 2
borkdude21:06:44

I updated the issue here, I think the js/Function thing is interesting, I'll try it when I have some time after the bb conf. Or perhaps @U5H74UNSF feels like hacking on this with me tomorrow ;) https://github.com/babashka/sci/issues/564

Sam Ritchie21:06:46

I’ve got it worked out for now, turns out I could close over the object that was eventually passed to my callback as this, since I had just created it when I registered the callback

borkdude21:06:11

yeah, that's how I usually work around it too

borkdude09:06:07

I tried a couple of things, but I'm still getting the global object in SCI for "this":

cljs.user=> (def obj (sci/eval-form (sci/init {:bindings {'thisAs (js/Function. "return this") }}) (do (def obj (clj->js {:f (fn [] (thisAs))})) (.f obj))))
#'cljs.user/obj
cljs.user=> (identical? obj js/globalThis)
true

borkdude09:06:58

ah wait:

cljs.user=> (sci/eval-form (sci/init {:bindings {'thisAs (js/Function. "return this") }}) (do (def obj (clj->js {:fn thisAs})) (.fn obj)))
#js {:fn #object[anonymous]}

borkdude09:06:30

so it doesn't work when you add the thisAs in a wrapped function

borkdude09:06:45

I wish I could make this work:

(sci/eval-form (sci/init {:bindings {'thisAs (js/Function. "return this") }}) (do (def obj (clj->js {:fn (fn [] (thisAs))})) (.fn obj)))
since then I could probably also make this-as work, but it seems thisAs needs to be directly on the object

borkdude14:06:28

@U017QJZ9M7W unchecked-set/get may be more "idiomatic" than aget/set, even though the docs say it's internal ;)

borkdude14:06:51

oh not exposed in SCI it seems

borkdude14:06:00

but could do that (issue/PR welcome)

borkdude14:06:09

ah well, aget/set works