How can I see my node.js variables already initiated? - node.js

I'm pretty new to node.js and I was wondering: seeing as the scope of any variable created is set to a sort of global scope, is there any way of listing out what variable names have already been initiated?

node.js variables are generally not global. The default is that any variable declared at the top level of a module is only in the module scope and does not conflict or interfere with any other modules.
Only variables explicitly assigned to the global object are actually available globally.
global.myVar = "foo";
All others are contained within a smaller scope - module scope or a function scope within a module.
So, if you have a module like this:
var x = 3;
module.exports = function() {
return x;
}
Then, the variable x is not a global variable at all. It is contained with the scope of this module. It would not conflict with a variable in any other module of the same name.
Because top level variables in a module are actually local variables within a module function wrapper and Javascript does not provide any means of iterating the local variables within a function scope, there is no way to iterate all top level variables within a module scope.
If you wanted to be able to iterate all variables in some context, then you can use a different format and put them as properties on an object.
var obj = {};
obj.x = 3;
obj.y = 5;
// list all enumerable properties of obj
for (var prop in obj) {
console.log("property: " + prop + " = ", + obj[prop]);
}
FYI, you can also use a debugger like node-inspector to view all variables declared within any given scope. You set a breakpoint in that scope and then look at the local variables present at that breakpoint.

Related

How to set a puppet class variable from within a hiera_hash each loop?

hiera data
ae::namespace_by_fqdn_pattern:
'((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((client))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com': '/test/blah/regression/client'
'((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((server))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com': '/test/blah/regression/server'
class
class ae {
$namespace = hiera('ae::namespace')
$target_host_patterns = hiera('ae::target_host_patterns')
hiera_hash('ae::namespace_by_fqdn_pattern').each |String $pattern, String $ns| {
if $facts['networking']['fqdn'].match($pattern) {
$ae::namespace = "${ns}"
}
}
<snip>
... yields
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Illegal attempt to assign to 'ae::enforcerd_namespace'. Cannot assign to variables in other namespaces (file: /etc/puppetlabs/code/environments/ar/modules/ae/manifests/init.pp, line: 21, column: 13) on node dfw-ubuntu1604-client02.pp-devcos.us-central1.gcp.dev.blah.com
... anyone here know how to do this correctly? trying to conditionally override that $ae::namespace variable but i'm too puppet-ignorant to know how to get it working : (
the loop and the pattern matching bits work. just can't figure out how to correctly set that class variable from within the hiera_hash().each loop.
How to set a puppet class variable from within a hiera_hash each loop?
You cannot. The associated block of an each() call establishes a local scope for each iteration. Variable assignments within apply to that local scope, and therefore last only for the duration of one execution of the block. You cannot anyway assign a new value to a variable during its lifetime, so even if you could assign to a class variable from within an each() call, it would be difficult to use that capability (and your approach would not work).
There are several ways you could approach the problem without modifying the form of the data. You could leverage the filter() function, for example, but my personal recommendation would be to use the reduce() function, something like this:
$namespace = lookup('ae::target_host_patterns').reduce(lookup('ae::namespace')) |$ns, $entry| {
$facts['networking']['fqdn'].match($entry[0]) ? { true => $entry[1], default => $ns }
}
That does pretty much exactly what your original code seems to be trying to do, except that the selected namespace is returned by the reduce() call, to be assigned to a variable by code at class scope, instead of the lambda trying to assign it directly. Note also that it takes care not only of testing the patterns but of assigning the default namespace when none of the patterns match, as it needs to do because you can only assign to the namespace variable once.
so the solution i landed on was to change the hiera data to:
ae::namespace : '/test/blah/regression'
ae::namespace_patterns: ['((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((client))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com', '((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((server))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com']
ae::namespace_by_pattern:
'((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((client))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com': '/test/paypal/regression/client'
'((^dfw-oel6)|(^dfw-oel7)|(^dfw-ubuntu1604))-((server))([0-9]{2}).pp-devcos-ae.us-central1.gcp.dev.blah.com': '/test/paypal/regression/server'
then the class code to:
$pattern = hiera_hash('ae::namespace_patterns').filter |$pattern| {
$facts['networking']['fqdn'] =~ $pattern
}
if length($pattern) {
$namespace = hiera('ae::namespace_by_pattern')[$pattern[0]]
} else {
$namespace = hiera('ae::namespace')
}
definitely still open to better answers. just what my own hacking produced as workable so far through much trial and error.

Variables. scope inside of a cfmodule

I have a page with a name of
summary.cfm
inside of it:
<cfinclude template="view/totals.cfm>
view/totals.cfm
inside of it:
variables.grandTotalHTML = invoke("viewtotals, "doSummary", {...});
view/viewtotals.cfc
inside of it
<cfmodule template="summarytemplate.cfm" ...>
<!--- database is not passed in here --->
view/summarytemplate.cfm
Inside of it we have
param attributes.database = session.database;
...
databaseoverride = attributes.database;
...
<cfquery name="qData">
SELECT *
FROM [#variables.databaseoverride#]
...
</cfquery>
Now question
I don't know where the databaseoverride is coming from.
Does global page request scope?
Does it come from variables in viewtotals.cfc ?
Does the unscoped version override it?
The variables scope at the module level is local to the module. An unscoped variable in a module is in variables scope.
This line
databaseoverride = attributes.database;
is equivalent to
variables.databaseoverride = attributes.database;
so is setting the value used here
<cfquery name="qData">
SELECT *
FROM [#variables.databaseoverride#]
...
</cfquery>
(Too long for comments)
Just to elaborate on Dan's answer:
summary.cfm
Only shares a VARIABLES scope with the included template, "view/totals.cfm"
view/totals.cfm
Only shares a VARIABLES scope with the parent template, "summary.cfm"
view/viewTotals.cfc
Its VARIABLES scope is not shared with any of the calling templates (summary.cfm and view/totals.cfm)
Its VARIABLES are accessible to the cfmodule - through the CALLER scope (as are the function's local and arguments scopes)
view/summaryTemplate.cfm
Does not share its VARIABLES scope with anyone.
Can view/modify any scopes in the parent component (viewTotals.cfc) through the CALLER scope.
( The REQUEST scope is accessible to all of the scripts above.)

Declare a nodejs const from a variable?

Is it possible to programmatically declare a nodejs const from a variable (string?)
let myConsts = ["const1","const2","const3"];
myConsts.forEach(function(label){
defineConst(label,"value"); // I need this function
})
defineConst should define a const, something like the PHP "define" function, but for nodejs
No, you can't really do that in Javascript. For a bit, I thought maybe you could hack it with eval() which is pretty much always the wrong way to solve a programming problem, but even eval() won't introduce a new const variable to the current scope. It will introduce a new var variable to the current scope as in this:
// dynamic variable name
let varName = "test";
// create variable in the current scope
eval("var " + varName + " = 4;");
// see if that variable exists and has the expected value
console.log(test);
But, alas you can't do this with const. You can read more about why here: Define const variable using eval().
Whatever programming problem you are trying to solve can likely be solved in a much better way since you really shouldn't be introducing dynamically named local variables. It's much better to use something like a Map object or a regular object with dynamically named properties in order to keep track of values with dynamic names to them.
If you shared the actual programming problem you're trying to solve (rather than your attempted solution), we could advise further on the best code for that particular problem.
Here's an example of the ability to store dynamically named properties on an object:
let base = {};
// dynamic property name (any string value in this variable)
let varName = "test";
// set property value with dynamic property name
base[varName] = "Hello";
// can reference it either way
console.log(base[varName]);
console.log(base.test);
Or, it can be done using a Map object:
let base = new Map();
// dynamic Map element key (any string value in this variable)
let varName = "test";
// set Map element with dynamic key
base.set(varName, "Hello");
// can reference it either way by the key
console.log(base.get(varName));
console.log(base.get("test"));

Initialize class reference

I get null value of instrumentRented
when I run
public class RentalAgreement
{
private MusicalInstrument instrumentRented;
public RentalAgreement(Customer renter,
RentalDate dateRented,
MusicalInstrument instrumentRented){
customer = renter;
rentalDate = dateRented;
instrumentRented = instrumentRented;
How to initialize MusicalInstrument reference in RentalAgreement?
Use this.instrumentRented = instrumentRented;
Since the parameter has the same name as the field attribute, you need to prefix with an explicit this to specify the scope.
You must instantiate a class with the new operator.
So somehwere in your code must do
instrumentRented = new MusicalInstrument();
before you access it. After you have done this you can execute functions from that class.
instrumentRented.doSomething();
In the above code you seem to pass it in in the constructor, so this means the caller has to instantiate it.
However I would advise to adopt a naming convention where you can see if a variable is a class member or a local variable. In your above code the local variable has the same name as the parameter, so it will not be set as a member variable, instead you assign it to itself. You might get a warning about this, depending on the evironment (Not sure about this but Eclipse definitely warns somethign like this). This is called shadowing, so what you need to do is:
this.instrumentRented = instrumentRented;

NodeJS converting string to variable

I am trying to update the contents of a variable in nodejs with the use of a string.
In client side javascript this was done with the use of window[variable] however since there is no "window" in nodejs. I tried using "this" and "module", however all im getting is an empty object. need help thanks
Code Snippet:
var myVariable = 'Hello';
var exchangeVariable = 'myVariable';
this[exchangeVariable] = 'Hello World';
/*
myVariable should equal to 'Hello World!'
*/
Thanks!
Here's some background before I answer your question directly:
In JavaScript, objects can be either indexed by the dot notation (someObj.property) or by indexing them as you do in your example (someObj["property"])
In the browser, window is the global context that the browser evaluates your code within. Node uses a variable called global.
So, if you want to reference a variable you've defined globally:
> var someGlobalVar = "hi";
> var myLookupKey = "someGlobalVar";
> global[myLookupKey]
'hi'
However, this is generally considered very bad practice (in Node and the browser). There are a myriad of reasons for this, but I'm focusing on just one:
In Node, modules (each required file) should be treated as if they do not share global state (and in some cases, they cannot share state). I encourage you to read through the modules section of the node documentation if you are trying to share state across files.
You could create your own variables hash or array and assign the variable yourself.
var myVariable = "Hello";
var varArray = new Array()
varArray["exchangeVariable"] = myVariable;

Resources