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 ). 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 <mari...@medikoo.com>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<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<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<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/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/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/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/2336508/javascript-get-access-to-local-variable-or-variable-in-closure-by-its-name> >>> >>> http://stackoverflow.com/**questions/1119335/javascript-** >>> local-variable-declare<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 <mari...@medikoo.com>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/**Sim**pleTags/blob/master/test/**expor** >>>>> tsTo.js<https://github.com/ajlopez/SimpleTags/blob/master/test/exportsTo.js> >>>>> >>>>> I want the DSL functions to be accesible as: >>>>> >>>>> require('simpletags').**exportsT**o(????); // ???? == 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("**TheNext**BigThing"))); >>>>> >>>>> 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<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 nodejs@googlegroups.com >>>> To unsubscribe from this group, send email to >>>> nodejs+unsubscribe@**googlegroups.com<nodejs%2bunsubscr...@googlegroups.com> >>>> For more options, visit this group at >>>> http://groups.google.com/**group/nodejs?hl=en?hl=en<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 nodejs@googlegroups.com >> To unsubscribe from this group, send email to >> nodejs+unsubscr...@googlegroups.com >> 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 nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en