On Tue, Mar 22, 2016 at 11:05 AM Giovanni Campagna < scampa.giova...@gmail.com> wrote:
> Ok, let's try a factual response... > Oops; that will teach me to check first and not try to answer from memory :-/ > > On Tue, 2016-03-22 at 17:24 +0000, Andrea Giammarchi wrote: > > > There is not even any Gio.LocalFile known to JS. > > > > ```js > > const a = imports.gi.Gio.File.new_for_path('./a.js'); > > > > // here the "now known to JS" Gio.LocalFile.prototype > > Object.getPrototypeOf(a).shenanigans = true; > > > > const b = imports.gi.Gio.File.new_for_path('./b.js'); > > > > // all instances affected indeed > > print(b.shenanigans); // true > > ``` > > > > > It's not exposed in the GIR file, so there is never a prototype > > object created in the first place > > Yes, there is a prototype object created. Every JS object with custom > behavior has a custom prototype object in SpiderMonkey, that's just how > it is. > > This prototype object is "GLocalFile", and it's stored in an invisible > object that exists just to reference it, as well as other hidden > classes that appear through GType but not through introspection. > > It's supposed to be mostly invisible, but it's unavoidable. > > > There is: > > > > ```js > > const a = imports.gi.Gio.File.new_for_path('./a.js'); > > // here the *shared* Gio.LocalFile.prototype > > Object.getPrototypeOf(a); > > ``` > > > > > In GJS, you can check if an object implements an interface with > > myObj.constructor.implements(Gio.File). > > > > That's good to know, thanks, yet if you read first messages of this > > thread it was about patching upfront and not at runtime. > > I understand I can find at runtime pretty much anything I want, but > > since there is an introspection ability, why are there undocumented > > instances around with undocumented prototypes? > > > > Or better, why `Gio.File.new` creates something unrelated with > > `Gio.File.prototype` or `Gio.File` methods ? > > Since this super secret thing is easily leaked, why not fixing this > > instead of saying that it shouldn't be known? > > You can't fix that. > > The truth is, Gio.File is a lie. > Indeed, Gio.File.prototype.replace_contents !== > (Gio.File.new_for_path('/foo')).replace_contents > > What it means is that Gio.File is an object that exists only to hold > methods that quack like the actual interface methods, if you call them > explicitly with say > Gio.File.prototype.replace_contents.call(file, "bla") > , but has nothing to do with the interface methods exposed on each > object. > > The reason for this is that prototype inheritance is single, but a > GObject class can have multiple interfaces, so there is no good place > to put Gio.File.prototype on the prototype chain from file to > Object.prototype (in a way that's generic and consistent with say, > Gtk.Label and Gtk.Buildable). > So what happens is that every class that also implements an interface > will resolve all interface methods on its own prototype. > > In the Gtk.Label case, Gtk.Label implements Gtk.Buildable and > Gtk.Widget implements Gtk.Buildable, both visible in the GIR, which > means > Gtk.Label.prototype.hasOwnProperty('custom_tag_start') === true > and > Gtk.Widget.prototype.hasOwnProperty('custom_tag_start') === true > > In the GLocalFile case, GLocalFile implements Gio.File, and we know > that from GType at runtime, so > window.<invisible > name>.GLocalFile.prototype.hasOwnProperty('replace_contents') === true > but you don't know that unless you poke at Object.getPrototypeOf > > Yes, this is very awkward if you monkey patch prototypes, but that's > just how it is. > > > The reason I've asked is that I've discovered there are hidden > > classes the GIR won't tell me, doesn't know, but **are** on my way. > > > > > I don't believe Spidermonkey would support overloading instanceof > > for this > > > > `instanceof` is the most easily "overloaded" ( not actually > > overloaded, it just checks > > `rightSide.prototype.isPrototypeOf(leftSide)` ) operator which is why > > I am asking if this would ever be solved. > > Now, if we tell a lie, we should at least be consistent about it, and > that's why > Gio.File.new_for_path('/') instanceof Gio.File > should return true > > Checking the prototype would not work, but instanceof can be overloaded > "properly", because after all we have access to the C API of SM and we > can do what we want. > > Indeed, that's https://bugzilla.gnome.org/show_bug.cgi?id=587030 > which has had patches for a while and probably needs a rebase, but > would make the Gio.File lie less visible to programmers. > > Hope this clarifies the situation, and cheers, > > Giovanni
_______________________________________________ javascript-list mailing list javascript-list@gnome.org https://mail.gnome.org/mailman/listinfo/javascript-list