Yeah, I wanted to avoid anything too complex in favour of a simple, self-contained approach. Which is why I regret bringing it up, since I realise I was probably trying to adhere to the virtues of simplicity a little too strongly.
For anybody interested, it was for parsing command-line input: https://github.com/Alhadis/MA-Scraper/blob/master/src/main.js I caved and simply whitelisted the expected class names instead. Undesirable, but more favourable than an overly-convoluted class map. On 09/12/2015 5:55 PM, <[email protected]> wrote: > Send es-discuss mailing list submissions to > [email protected] > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.mozilla.org/listinfo/es-discuss > or, via email, send a message with subject or body 'help' to > [email protected] > > You can reach the person managing the list at > [email protected] > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of es-discuss digest..." > > Today's Topics: > > 1. Re: Indirect references to variables (Robin Cafolla) > > > ---------- Forwarded message ---------- > From: Robin Cafolla <[email protected]> > To: "[email protected]" <[email protected]> > Cc: > Date: Wed, 9 Dec 2015 08:55:03 +0200 > Subject: Re: Indirect references to variables > You're probably better off building some sort of class map into your > application to handle this. > > Either > > A) You have all your classes loaded in one scope, you can have a map of > strings to those classes which a method can retrieve and instantiate. > Drawback is that your method (and the map) needs to also be defined in the > same scope. > > or > > B) You don't have all classes in scope and are loading them dynamically > (with something like requirejs), in which case your function needs a > class-map of class names to paths, which your loader can pull in for you > and asynchronously create. I tend towards using a service manager pattern > to do this in applications where I have a requirement. > > In the second instance you could introduce a compile step to create your > class map. Very much dependent on your workflow. Regardless of how you're > loading your classes or how you're scoping your code, some sort of class > map is the solution. > > The only case I can think of where loading by string really becomes an > issue is with ES6 modules, which AFAIK, being static would need to all be > loaded at the top of the module where you're de-serializing your classes. > > When ES6 modules start landing in browsers I'll be tending even more > strongly towards the service manager pattern: One known place to resolve > instances and factories for classes. > > Regards, > > Robin Cafolla > > On 9 December 2015 at 08:46, <[email protected]> wrote: > >> Send es-discuss mailing list submissions to >> [email protected] >> >> To subscribe or unsubscribe via the World Wide Web, visit >> https://mail.mozilla.org/listinfo/es-discuss >> or, via email, send a message with subject or body 'help' to >> [email protected] >> >> You can reach the person managing the list at >> [email protected] >> >> When replying, please edit your Subject line so it is more specific >> than "Re: Contents of es-discuss digest..." >> >> Today's Topics: >> >> 1. Re: Indirect references to variables (Jordan Harband) >> 2. Re: Indirect references to variables (John Gardner) >> >> >> ---------- Forwarded message ---------- >> From: Jordan Harband <[email protected]> >> To: John Gardner <[email protected]> >> Cc: es-discuss <[email protected]> >> Date: Tue, 8 Dec 2015 22:39:51 -0800 >> Subject: Re: Indirect references to variables >> Can you not put each class in its own module, and simply require, by >> name, the one you want? >> >> On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[email protected]> >> wrote: >> >>> Only at top-level. This issue actually surfaced when I realised I had no >>> way to indirectly access classes by name... and for some reason, neither >>> the global object nor the eval hack were returning anything. It worked fine >>> for simple variables, so I wondered if that was an intentional side-effect >>> of classes in ECMAScript. >>> >>> (Of course, if not, it may actually be an issue with V8's >>> implementation...) >>> On 09/12/2015 5:05 PM, "Bradley Meck" <[email protected]> wrote: >>> >>>> Are you putting hundreds of classes into a single scope? >>>> >>>> On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[email protected]> >>>> wrote: >>>> >>>>> Trouble is, if one has literally hundreds of classes or functions that >>>>> need to be matched, they'd rather not pool them all into one massive >>>>> object >>>>> literal for the sake of easier mapping. DRY principle fully relevant. >>>>> >>>>> Also, yes, while it would be a pain for static type analysis, it >>>>> wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, >>>>> whereas the indirect references would only point to modifiers only: >>>>> >>>>> var className = \"doSomethingSinister(/etc/passwd/);" >>>>> >>>>> That line would literally be looking for a property in the current >>>>> scope that'd be named this: >>>>> >>>>> global["doSomethingSinister(/etc/passwd/);"] >>>>> window["doSomethingSinister(/etc/passwd/);"] >>>>> >>>>> >>>>> >>>>> On 9 December 2015 at 16:09, Frankie Bagnardi <[email protected]> >>>>> wrote: >>>>> >>>>>> This is a common situation, but one easily solved by object literals. >>>>>> Reflecting on the scope is confusing and would hurt tooling (it's >>>>>> essentially eval). >>>>>> >>>>>> ```js >>>>>> var mapping = {Polygon: Polygon}; >>>>>> var meshClass = mapping[ajaxData.className]; >>>>>> ``` >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> ECMAScript currently offers no clean way to "dereference" a variable >>>>>>> in the current scope. For instance, assume an author wishes to obtain a >>>>>>> reference to a class using a variable that holds its name: >>>>>>> >>>>>>> class Paintbrush{ } >>>>>>> >>>>>>> let className = "Paintbrush"; >>>>>>> >>>>>>> // Would only work in browsers, not NodeJS >>>>>>> console.log( window[className] ); >>>>>>> >>>>>>> // Doesn't even work in NodeJS >>>>>>> console.log( global[className] || this[className] ); >>>>>>> >>>>>>> A hacky workaround is to create an anonymous function that simply >>>>>>> returns a reference to the named variable: >>>>>>> >>>>>>> function dereference(name){ >>>>>>> return new Function([], "return " + name)(); >>>>>>> } >>>>>>> dereference("Paintbrush") === Paintbrush; // true >>>>>>> >>>>>>> This isn't an elegant solution, nor a preferable one. Another >>>>>>> approach might be to leverage `eval`, which opens up the obvious issues >>>>>>> of >>>>>>> performance and security. >>>>>>> >>>>>>> Having a way of indirectly referencing another variable would fix >>>>>>> this: >>>>>>> >>>>>>> class Paintbrush{ } >>>>>>> >>>>>>> let className = "Paintbrush"; >>>>>>> >>>>>>> let classReference = \className; >>>>>>> console.log(classReference === Paintbrush); // true >>>>>>> >>>>>>> Sticking a backslash before a bareword identifier creates a >>>>>>> reference to an object whose name matches the identifier's string >>>>>>> value. If >>>>>>> no such object exists in the current scope, it simply returns >>>>>>> `undefined`. >>>>>>> >>>>>>> I can't see this being used in everyday programs, but it would >>>>>>> facilitate Ajax programming considerably, where classes or functions can >>>>>>> only be specified by name: >>>>>>> >>>>>>> {"className":"Polygon", "vertices": [[0,0]...] } >>>>>>> >>>>>>> let meshClass = \ajaxData.className; >>>>>>> if(meshClass instanceof Mesh){ >>>>>>> new meshClass(ajaxData.vertices); >>>>>>> } >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> [email protected] >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> [email protected] >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> [email protected] >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> >> ---------- Forwarded message ---------- >> From: John Gardner <[email protected]> >> To: Jordan Harband <[email protected]> >> Cc: es-discuss <[email protected]> >> Date: Wed, 9 Dec 2015 17:46:26 +1100 >> Subject: Re: Indirect references to variables >> >> Never mind. This is beginning to south like too much of a damn edge case >> for it to be of language-wide relevance. >> >> Pretend this discussion never happened. >> On 09/12/2015 5:40 PM, "Jordan Harband" <[email protected]> wrote: >> >>> Can you not put each class in its own module, and simply require, by >>> name, the one you want? >>> >>> On Tue, Dec 8, 2015 at 10:19 PM, John Gardner <[email protected]> >>> wrote: >>> >>>> Only at top-level. This issue actually surfaced when I realised I had >>>> no way to indirectly access classes by name... and for some reason, neither >>>> the global object nor the eval hack were returning anything. It worked fine >>>> for simple variables, so I wondered if that was an intentional side-effect >>>> of classes in ECMAScript. >>>> >>>> (Of course, if not, it may actually be an issue with V8's >>>> implementation...) >>>> On 09/12/2015 5:05 PM, "Bradley Meck" <[email protected]> wrote: >>>> >>>>> Are you putting hundreds of classes into a single scope? >>>>> >>>>> On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <[email protected]> >>>>> wrote: >>>>> >>>>>> Trouble is, if one has literally hundreds of classes or functions >>>>>> that need to be matched, they'd rather not pool them all into one massive >>>>>> object literal for the sake of easier mapping. DRY principle fully >>>>>> relevant. >>>>>> >>>>>> Also, yes, while it would be a pain for static type analysis, it >>>>>> wouldn't necessarily be the same as `eval`. Eval executes arbitrary code, >>>>>> whereas the indirect references would only point to modifiers only: >>>>>> >>>>>> var className = \"doSomethingSinister(/etc/passwd/);" >>>>>> >>>>>> That line would literally be looking for a property in the current >>>>>> scope that'd be named this: >>>>>> >>>>>> global["doSomethingSinister(/etc/passwd/);"] >>>>>> window["doSomethingSinister(/etc/passwd/);"] >>>>>> >>>>>> >>>>>> >>>>>> On 9 December 2015 at 16:09, Frankie Bagnardi <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> This is a common situation, but one easily solved by object >>>>>>> literals. Reflecting on the scope is confusing and would hurt tooling >>>>>>> (it's >>>>>>> essentially eval). >>>>>>> >>>>>>> ```js >>>>>>> var mapping = {Polygon: Polygon}; >>>>>>> var meshClass = mapping[ajaxData.className]; >>>>>>> ``` >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Tue, Dec 8, 2015 at 9:53 PM, John Gardner <[email protected] >>>>>>> > wrote: >>>>>>> >>>>>>>> ECMAScript currently offers no clean way to "dereference" a >>>>>>>> variable in the current scope. For instance, assume an author wishes to >>>>>>>> obtain a reference to a class using a variable that holds its name: >>>>>>>> >>>>>>>> class Paintbrush{ } >>>>>>>> >>>>>>>> let className = "Paintbrush"; >>>>>>>> >>>>>>>> // Would only work in browsers, not NodeJS >>>>>>>> console.log( window[className] ); >>>>>>>> >>>>>>>> // Doesn't even work in NodeJS >>>>>>>> console.log( global[className] || this[className] ); >>>>>>>> >>>>>>>> A hacky workaround is to create an anonymous function that simply >>>>>>>> returns a reference to the named variable: >>>>>>>> >>>>>>>> function dereference(name){ >>>>>>>> return new Function([], "return " + name)(); >>>>>>>> } >>>>>>>> dereference("Paintbrush") === Paintbrush; // true >>>>>>>> >>>>>>>> This isn't an elegant solution, nor a preferable one. Another >>>>>>>> approach might be to leverage `eval`, which opens up the obvious >>>>>>>> issues of >>>>>>>> performance and security. >>>>>>>> >>>>>>>> Having a way of indirectly referencing another variable would fix >>>>>>>> this: >>>>>>>> >>>>>>>> class Paintbrush{ } >>>>>>>> >>>>>>>> let className = "Paintbrush"; >>>>>>>> >>>>>>>> let classReference = \className; >>>>>>>> console.log(classReference === Paintbrush); // true >>>>>>>> >>>>>>>> Sticking a backslash before a bareword identifier creates a >>>>>>>> reference to an object whose name matches the identifier's string >>>>>>>> value. If >>>>>>>> no such object exists in the current scope, it simply returns >>>>>>>> `undefined`. >>>>>>>> >>>>>>>> I can't see this being used in everyday programs, but it would >>>>>>>> facilitate Ajax programming considerably, where classes or functions >>>>>>>> can >>>>>>>> only be specified by name: >>>>>>>> >>>>>>>> {"className":"Polygon", "vertices": [[0,0]...] } >>>>>>>> >>>>>>>> let meshClass = \ajaxData.className; >>>>>>>> if(meshClass instanceof Mesh){ >>>>>>>> new meshClass(ajaxData.vertices); >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> [email protected] >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> [email protected] >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss > >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

