How do I re-link the library use require? (nodejs) - node.js

For example
I have file 1
[{"a1":1}]
And file 2
var obj1 = JSON.parse(fs.readFileSync("./файл 1.JSON" , "UTF-8"));
module.exports.obj1 = obj1
I start program...
for(i=0; ; i++) {
console.log(require('./файл 2').a1);
let bb = JSON.parse(fs.readFileSync("./файл 1.JSON" , "UTF-8"));
console.log(bb.a1);
(there pause for slowed)
}
And at that time I correct file 1. Then I will see it in fs, but don't see in require.
Now the question: how to make, so that require show the new value?

When node executes your program and executes a require statement, it loads any modules. It then caches those modules so that subsequent requests for the same module give the same code. So in your example, on the first time through the loop, file 2 is going to be initialized with whatever value it reads from the JSON file and it won't be re-initialized.
Modules are intended to be static bundles of code and using require to include the same module multiple times is supposed to return the same module. For dynamic values like your JSON file, use fs functions to access the values at the time they're needed.

Related

How to pass a random parameter to the response in SOAPUI, which would change every n calls

I am new in soapui. I make logic for a service stub and I meet a problem.
I have a simple service stub that returns a parameter with a random number (it is randomized in the answer in groovy language), but the problem is that this number is used 2 times per session and cannot be changed, otherwise the session will fail. How would I pass a random number to the next response and then start randomizing again and so on?
I could not find anything similar to my case on the Internet, so I ask the question here. Is it even possible to implement this in soapui, for example through TestSuite and groove scripts?
Groovy code I use in response script to generate random number:
requestContext.actreq = (10000000 + Math.abs(new Random().nextInt() % 9999999));
Then I substitute ${actreq} in the response
If the number 100001 is generated, then I would like to pass it to the next two response. In order for Random to work every 2 iterations.
you could try this aproach
class Glob{
static long callCount=0
static long randValue=0
static long rand(){
callCount ++
if(callCount % 2 == 1){
randValue = (10000000 + Math.abs(new Random().nextInt() % 9999999))
}
return randValue
}
}
requestContext.actreq = Glob.rand()
or official way like this:
https://www.soapui.org/docs/functional-testing/working-with-scripts/
use setup script to assign context variables
in script you could access those variables like i did in code above to increment call-count and re-calculate random if needed...

Edit Data of Unpickled Objects

I am attempting to use pickle to save a dictionary that includes class instances since json, which I usually use, cannot save class instances. I plan to be able to load them and be able to modify the data I have loaded. Whenever I run a function from the class instances, that would normally change their data, it doesn't. They are readable and can still run their functions, but the data just doesn't change. Below I have put the code for loading the data, with players being a list of the?e class instances, and I put a snippet of code from inside one of the class functions. How do I fix this
species = pickle.load(open("species.obj","rb"))
vLanguage = species["lang"]
players = species["instances"]
speciesName = species["species"]
# In separate file imported before pickle data is loaded
def turn(self,env):
if (randint(0,100)/100) < env.wound:
self.wound = True
if log:
print(f"{self.id} was wounded searching for {action}")
# If this came out as true, and self.wound was False, it would stay as False

Set/Modify the variable used in a function from imported module

Consider following code:
##testing.py
namespace = "original"
def print_namespace():
print ("Namespace is", namespace)
def get_namespace_length(_str = namespace):
print(len(_str))
##Main
import testing
testing.namespace = "test"
testing.printnamespace()
testing.get_namespace_length()
print_namespace() return 'test' as exepcted, but the get_namespace_length() still return 8 which is the length of 'original'. How can I make get_namespace_length() taking the modified variable?
The use case of such implementation is some functions are used the same variable in the imported module, if I can modify/set variable, I can avoid explicitly to call out new variable in each function. Can someone advise?
Also, it doesn't have to be implemented in the way shown above, as long as it works. (global variable etc.)
Um... your default argument for get_namespace_length is database, undefined in your code snippet, also you switch from calling testing to test (I'm guessing that was one of many typos).
In short though, I believe its to do with how the bytecode is compiled in python. Arguments are 'preloaded', and therefore a change to a variable (such as namespace) does not get included in the compilation of get_namespace_length. If I remember correctly, upon import the entire code of the imported file is compiled and executed (try putting a print() statement at the end of testing.py to see)
So what you really want to do to obtain your length of 4 is change testing.py to:
namespace = "original"
def print_namespace():
print ("Namespace is", namespace)
def get_namespace_length():
_str = namespace
print(len(_str))
Or just print(len(namespace)).
Hope that helps!

Pass JSON as command line argument to Node

I'd like to pass a JSON object as a command line argument to node. Something like this:
node file.js --data { "name": "Dave" }
What's the best way to do this or is there another more advisable way to do accomplish the same thing?
if its a small amount of data, I'd use https://www.npmjs.com/package/minimist, which is a command line argument parser for nodejs. It's not json, but you can simply pass options like
--name=Foo
or
-n Foo
I think this is better suited for a command line tool than json.
If you have a large amount of data you want to use you're better of with creating a json file and only pass the file name as command line argument, so that your program can load and parse it then.
Big objects as command line argument, most likely, aren't a good idea.
this works for me:
$ node foo.js --json-array='["zoom"]'
then in my code I have:
import * as _ from 'lodash';
const parsed = JSON.parse(cliOpts.json_array || []);
_.flattenDeep([parsed]).forEach(item => console.log(item));
I use dashdash, which I think is the best choice when it comes to command line parsing.
To do the same thing with an object, just use:
$ node foo.js --json-object='{"bar": true}'
This might be a bit overkill and not appropriate for what you're doing because it renders the JSON unreadable, but I found a robust way (as in "works on any OS") to do this was to use base64 encoding.
I wanted to pass around lots of options via JSON between parts of my program (a master node routine calling a bunch of small slave node routines). My JSON was quite big, with annoying characters like quotes and backslashes so it sounded painful to sanitize that (particularly in a multi-OS context).
In the end, my code (TypeScript) looks like this:
in the calling program:
const buffer: Buffer = new Buffer(JSON.stringify(myJson));
const command: string = 'node slave.js --json "' + buffer.toString('base64') + '" --b64';
const slicing: child_process.ChildProcess = child_process.exec(command, ...)
in the receiving program:
let inputJson: string;
if (commander.json) {
inputJson = commander.json;
if (commander.b64) {
inputJson = new Buffer(inputJson, 'base64').toString('ascii');
}
}
(that --b64 flag allows me to still choose between manually entering a normal JSON, or use the base64 version, also I'm using commander just for convenience)

Load R package from character string

I want to create a function which includes loading a package that I make within the function. A short example (which doesn't run!):
loadMe <- function(name){
genLib(xxx, libName = name) #make a new library with name "name"
library(name) #load the new library...
}
This does not work! A bit of reproducible code which illustrates my main problem:
library(ggplot) #this works fine
load.this <- "ggplot"
library(load.this) #I want this to load ggplot!
I know the problem is that library() and require() take as an argument an object name which does not exist yet. I have tried wrapping my character string with parse(), deparse(), substitute(), expression(), quote(), etc etc. These all return the same problem:
library(load.this)
# Error in library(loadss) : there is no package called 'loadss'
library(deparse(load.this))
# Error in library(deparse(loadss)) : 'package' must be of length 1
Is there a way to do this?
Use the character.only argument
foo <- "ggplot2"
library(foo,character.only=TRUE)
You say that you have tried using parse(). The following seems to work for me:
eval(parse(text = 'library(MASS)')[1])

Resources