On Saturday, July 7, 2012 at 10:28 AM, Mariusz Nowak wrote:
> This is the use case we were missing, you want to do same thing I've once
> tried to do in domjs https://github.com/medikoo/domjs
> Currently I think there's no better solution than polluting global scope.
> In domjs I resolved it by introducing dynamic scope (
> https://github.com/medikoo/domjs/blob/master/lib/dscope.js ).
>
>
This is a good use case for WeakMaps; they aren't available in v8 stable yet,
but would eliminate the leaky references that could be held in the current
implementation.
Rick
> but it's not great approach as variable assignments live only during
> function execution, and that's confusing. I think best solution would to be
> have possibility to run modules in some predefined lexical scope, but it's
> not that easy to achieve.
>
> On Saturday, July 7, 2012 3:55:26 PM UTC+2, ajlopez wrote:
> > Thanks!
> >
> > I usually do in your suggested way, and I'm with you. But in this special
> > case, I feel the user of my module could find a bit weird to write
> >
> > var st = require('simpletags');
> >
> > st.html(st.head(st.title('...')), st.body(st.h1(....))
> >
> > instead
> >
> > html(head(title('....')), body(h1('...'))
> >
> > in a controlled way (only in its own module). I want to give him/her an
> > option. Ruby has it (as an option, too). It's the first time I found I
> > needed it in Node.js. Usually, I assert "Ruby ceremony > Javascript/Node.js
> > ceremony", but now, I was trapped by this issue.
> >
> > My best solutions:
> >
> > a)
> > var st = require(...); // and use with st.h1, st.h2...
> >
> > b)
> > require('simpletags').exportsTo(global); // maybe in browser I could export
> > to windows directly in the module
> >
> > c)
> > var simpletags = require('simpletags');
> > eval(simpletags.exportLocalCode()); // where .exportLocalCode returns a
> > String with "var h1 = simpletags.h1; ... "
> > c2)
> > var st = require('simpletags');
> > eval(st.exportLocalCode('st')); // the local variable name 'st' should be
> > informed to be used in var ...= .... string result
> >
> > On Sat, Jul 7, 2012 at 10:38 AM, Mariusz Nowak <[email protected]
> > (mailto:[email protected])> wrote:
> > > In modules you can achieve the same by assigning function to global: e.g.
> > > `global.foo = function () { .. }` it will work same as `this.foo =
> > > function () { ... }` in REPL. but I would strongly discourage this,
> > > relying on global scope is bad practice.
> > >
> > > I'd say that unless you're using regular require/export logic to share
> > > objects between modules, you're doing something wrong. Try to think just
> > > with require/exports and then you should quickly find way home. See how
> > > module relations in other packages work.
> > >
> > > --
> > > Mariusz Nowak
> > > https://github.com/medikoo
> > > http://twitter.com/medikoo
> > >
> > >
> > > On Saturday, July 7, 2012 3:18:51 PM UTC+2, ajlopez wrote:
> > > > Thanks for the suggestion!.... but... I missing some part of your
> > > > answer.
> > > >
> > > > I guess I understand the difference btw global, this.property, and var
> > > > local. And then, I understand why it not works. What I don't understand
> > > > is how to circumvent/solve the problem. I don't know if your answer is:
> > > >
> > > > a- " you'll get the answers :) " and then, you will know that it's
> > > > impossible to solve, or too weird
> > > > b- you'll get the answers :) " and it's possible in this (simple)
> > > > way.....etc...
> > > >
> > > > AFAIK, it's "a". Am I right?
> > > >
> > > > My problem is:
> > > >
> > > > - module1 requires module2
> > > > - I want to use the exposed functions of module2 as they were defined
> > > > in module1, using dynamic names. That is, it's not a solution
> > > >
> > > > var module2 = require('module2');
> > > > var Function2 = module2.Function2;
> > > >
> > > > Usually, I did a bit of experiment at REPL. I found that this works:
> > > >
> > > > var name = 'Function2';
> > > > this[name] = ...
> > > >
> > > > var obj = new Function2(); // without using this
> > > >
> > > > BUT it's only works at REPL. So, encouraged by this discovery (I
> > > > expected it will not work), I hoped to make it works in other context.
> > > >
> > > > Now, I understand why it is work in REPL. Notably, in REPL
> > > >
> > > > this == global
> > > >
> > > > so it's possible to emulate
> > > >
> > > > var foo = ...
> > > >
> > > > with something like (pseudocode)
> > > >
> > > > name = 'foo'
> > > > var [name] = .....
> > > >
> > > > writing
> > > >
> > > > name = 'foo';
> > > > this[name] = ...
> > > >
> > > > and then foo is available "as if it is" a local var.
> > > >
> > > > But inside a running .js, this is not equal to global. I was tricked by
> > > > REPL ;-)
> > > >
> > > > So, the better solution I found so far is to put something like this in
> > > > module1:
> > > > //
> > > > http://stackoverflow.com/questions/5625569/include-external-js-file-in-node-js-app
> > > >
> > > >
> > > > var fs = require('fs');
> > > > var vm = require('vm');
> > > >
> > > > var includeInThisContext = function(path) {
> > > > var code = fs.readFileSync(path);
> > > > vm.runInThisContext(code, path);
> > > > }.bind(this);
> > > >
> > > > includeInThisContext(__dirname + '/module2.js');
> > > >
> > > > console.log(foo); // it's defined
> > > >
> > > > where module2 define foo:
> > > >
> > > > foo = {};
> > > >
> > > > BUT IN MY CASE, module2 doesn't define the functions at its own context:
> > > > https://github.com/ajlopez/SimpleTags/blob/master/lib/simpletags.js
> > > > it uses an array to dynamically define and export functions. I never
> > > > have
> > > >
> > > > function h1() {
> > > > }
> > > >
> > > > function h2() {
> > > > }
> > > >
> > > > defined at module2 context. And I don't want this. My DSL defines a
> > > > function for each HTML tag.
> > > >
> > > > Now, I want to have these dynamically defined functions from module2
> > > > accessible in outer module1, as they were local to it.
> > > >
> > > > I could write inside my module,
> > > >
> > > > var h1 = makeTag('h1');
> > > > var h2 = makeTag('h2");
> > > > ...
> > > > ....
> > > >
> > > > for dozens of tags, and then use something like
> > > > includeInThisContext.... but I feel it's too weird.
> > > >
> > > > Apparently, my problem is: I didn't find a way to define a local var
> > > > with a dynamic name.
> > > >
> > > > The original DSL in Ruby:
> > > > https://github.com/dlitvakb/deklarativna/blob/master/test/test_deklarativna.rb
> > > >
> > > >
> > > > use "include dslmodule". And inside the dsl module, it defines
> > > > dynamically named functions at module top level. So the functions are
> > > > automatically available to the module that makes the includes.
> > > >
> > > > That is the "trick" I didn't found how to emulate in
> > > > Node.js/require/CommonJS world.
> > > >
> > > > Some links in my research:
> > > > http://stackoverflow.com/questions/5833978/javascript-how-to-use-dynamic-local-variables
> > > >
> > > > http://stackoverflow.com/questions/5094862/how-do-i-access-a-local-variable-dynamically-via-a-string-form-of-its-name-fro
> > > >
> > > > http://stackoverflow.com/questions/598878/how-can-i-access-local-scope-dynamically-in-javascript
> > > >
> > > > http://stackoverflow.com/questions/2336508/javascript-get-access-to-local-variable-or-variable-in-closure-by-its-name
> > > >
> > > > http://stackoverflow.com/questions/1119335/javascript-local-variable-declare
> > > >
> > > >
> > > > The better approach I found in these links is to use eval (!!??):
> > > > eval("var "+name+ " = ....");
> > > >
> > > > Am I right? the only ways are the above ones? Or is another way?
> > > >
> > > > Any suggestions?
> > > >
> > > > Angel "Java" Lopez
> > > >
> > > >
> > > > On Sat, Jul 7, 2012 at 9:27 AM, Mariusz Nowak <[email protected]
> > > > (mailto:[email protected])> wrote:
> > > > > @ajlopez get to know how variable scoping in JavaScript works (what
> > > > > is global, how this and how local variable works), and you'll get the
> > > > > answers :)
> > > > >
> > > > >
> > > > > On Saturday, July 7, 2012 2:11:56 PM UTC+2, ajlopez wrote:
> > > > > > Hi people!
> > > > > >
> > > > > > A very simple question. When I write in the Node repl:
> > > > > >
> > > > > > this.foo = 'bar';
> > > > > > console.log(foo);
> > > > > >
> > > > > > it's ok, foo is defined. But writing that code in file.js and
> > > > > > running
> > > > > >
> > > > > > node file.js
> > > > > >
> > > > > > then foo is not defined.
> > > > > >
> > > > > > Or require('file.js'), then foo is not defined.
> > > > > >
> > > > > > Any way to define a variable in the "current context"? Apparently,
> > > > > > "this" properties and "current context" top variables are the same
> > > > > > in REPL, but they are not the same in .js, or inside a required
> > > > > > module.
> > > > > >
> > > > > > I want to do this in a dynamic way:
> > > > > >
> > > > > > name = 'foo';
> > > > > > // ...
> > > > > > this[name] = 'bar';
> > > > > >
> > > > > > so
> > > > > >
> > > > > > foo = 'bar';
> > > > > >
> > > > > > is not a solution in my context.
> > > > > >
> > > > > > I could use:
> > > > > >
> > > > > > global[name] = 'bar';
> > > > > >
> > > > > > but I want to expose the new "current context" top variables only
> > > > > > in my "current context" without pollute the global environment.
> > > > > >
> > > > > > I encountered this problem when coding a simple HTML DSL:
> > > > > > https://github.com/ajlopez/SimpleTags/blob/master/test/exportsTo.js
> > > > > > I want the DSL functions to be accesible as:
> > > > > >
> > > > > > require('simpletags').exportsTo(????); // ???? == global? this?
> > > > > > Now, I should use global to make it works in any situation
> > > > > >
> > > > > > then, use the exported function as functions in current context:
> > > > > >
> > > > > > html(body(h1("TheNextBigThing")));
> > > > > > instead
> > > > > >
> > > > > > var st = require("simpletags");
> > > > > >
> > > > > > st.html(st.body(st.h1("TheNextBigThing")));
> > > > > >
> > > > > > Any other way?
> > > > > >
> > > > > > TIA
> > > > > >
> > > > > > Angel "Java" Lopez
> > > > > > http://ajlopez.wordpress.com
> > > > > > @ajlopez
> > > > > > gh:ajlopez
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Job Board: http://jobs.nodejs.org/
> > > > > Posting guidelines:
> > > > > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> > > > > You received this message because you are subscribed to the Google
> > > > > Groups "nodejs" group.
> > > > > To post to this group, send email to [email protected]
> > > > > (mailto:[email protected])
> > > > > To unsubscribe from this group, send email to
> > > > > [email protected]
> > > > > (mailto:nodejs%[email protected])
> > > > > For more options, visit this group at
> > > > > http://groups.google.com/group/nodejs?hl=en?hl=en
> > > >
> > > --
> > > Job Board: http://jobs.nodejs.org/
> > > Posting guidelines:
> > > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> > > You received this message because you are subscribed to the Google
> > > Groups "nodejs" group.
> > > To post to this group, send email to [email protected]
> > > (mailto:[email protected])
> > > To unsubscribe from this group, send email to
> > > [email protected]
> > > (mailto:nodejs%[email protected])
> > > For more options, visit this group at
> > > http://groups.google.com/group/nodejs?hl=en?hl=en
> >
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
--
Job Board: http://jobs.nodejs.org/
Posting guidelines:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en