Indirect references to variables

Robin Cafolla robin at zombiemongoose.com
Wed Dec 9 06:55:03 UTC 2015


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, <es-discuss-request at mozilla.org> wrote:

> Send es-discuss mailing list submissions to
>         es-discuss at mozilla.org
>
> 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
>         es-discuss-request at mozilla.org
>
> You can reach the person managing the list at
>         es-discuss-owner at mozilla.org
>
> 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 <ljharb at gmail.com>
> To: John Gardner <gardnerjohng at gmail.com>
> Cc: es-discuss <es-discuss at mozilla.org>
> 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 <gardnerjohng at gmail.com>
> 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" <bradley.meck at gmail.com> wrote:
>>
>>> Are you putting hundreds of classes into a single scope?
>>>
>>> On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <gardnerjohng at gmail.com>
>>> 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 <f.bagnardi at gmail.com>
>>>> 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 <gardnerjohng at gmail.com>
>>>>> 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
>>>>>> es-discuss at mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>
>>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
>>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> ---------- Forwarded message ----------
> From: John Gardner <gardnerjohng at gmail.com>
> To: Jordan Harband <ljharb at gmail.com>
> Cc: es-discuss <es-discuss at mozilla.org>
> 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" <ljharb at gmail.com> 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 <gardnerjohng at gmail.com>
>> 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" <bradley.meck at gmail.com> wrote:
>>>
>>>> Are you putting hundreds of classes into a single scope?
>>>>
>>>> On Tue, Dec 8, 2015 at 11:56 PM, John Gardner <gardnerjohng at gmail.com>
>>>> 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 <f.bagnardi at gmail.com>
>>>>> 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 <gardnerjohng at gmail.com>
>>>>>> 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
>>>>>>> es-discuss at mozilla.org
>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>>>
>>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151209/3691e5c6/attachment-0001.html>


More information about the es-discuss mailing list