I'm trying to find out how to do this properly. What's happening is in "Task MyTask = new Task(() => Match.UserObject.InitUser(tmpUserObject));", tmpUserObject is getting evaluated when the task runs and not when it's declared. Since this seems to be a "feature", there must be a proper way to use the value of tmpUserObject at the time the task is declared.
Thanks :-)
Match.UserObject tmpUserObject;
while (myReader.Read())
{
if (tmpDict.TryGetValue(UserID, out tmpUserObject))
{
tmpUserObject.vchSchoolID.Add(myReader.GetString(5));
}
else
{
tmpUserObject = new Match.UserObject();
//Assign some values from reader...
//Do any processing eg. DoubleMetaphone pre-computation...etc...
Task MyTask = new Task(() => Match.UserObject.InitUser(tmpUserObject));
TaskList.Add(MyTask);
}
}
//Block until all the tasks are done
Task[] MyTaskArray = TaskList.ToArray();
Task.WaitAll(MyTaskArray);
From what I can tell of your code, tmpUserObject is a class instance. It is never "evaluated". The lambda that you pass to the task ( () => Match.UserObject.InitUser(tmpUserObject) ) is evaluated when the task is run, which does happen asynchronously. That's the purpose of the Task object.
What do you actually mean when you say "use the value of tmpUserObject"?
EDIT: To capture the value, you need to assign it to a new variable with each iteration. You can do this simply by re-scoping the variable to inside the loop:
while (myReader.Read())
{
// Since we moved this inside the loop, the variable's scope has changed.
Match.UserObject tmpUserObject;
if (tmpDict.TryGetValue(UserID, out tmpUserObject))
{
tmpUserObject.vchSchoolID.Add(myReader.GetString(5));
}
else
{
tmpUserObject = new Match.UserObject();
//Assign some values from reader...
//Do any processing eg. DoubleMetaphone pre-computation...etc...
Task MyTask = new Task(() => Match.UserObject.InitUser(tmpUserObject));
TaskList.Add(MyTask);
}
}
That's called a closure.
It's one of C#'s more powerful features.
If you want to evaluate the expression in advance, you can put it in a separate variable outside the lambda.
Related
I have this file that stores some of my environment variables.
Let's call it generalEnv.js
module.exports = {
CONSTANT_1: process.env.CONSTANT_1,
CONSTANT_2: process.env.CONSTANT_2
};
When the app initializes, I don't put the value of process.env.CONSTANT_1 in the env variables yet because I have to look into some places first if it exists(mongodb for instance). If it does not exists on mongodb, I will add a value into process.env.CONSTANT_1 and I was expecting that the value will reflect on generalEnv now.
When I tried accessing the CONSTANT_1 in another file.
Let's call it getConstantOne.js
const { CONSTANT_1 } = require('./generalEnv');
module.exports = () => {
// I was expecting that CONSTANT_1 will have a value here now
if(!CONSTANT_1) {
// do something
}
return CONSTANT_1
}
it does not reflect.. how do I update the closure of generalEnv.js for process.env.CONSTANT_1 to reflect on CONSTANT_1?
When assigning to a variable (or a value in an object/element in an array), the assignment will replace the value, not modify it. Therefore, any "copies" of that value will not be affected, and remain the same. Consider this example:
let a = 0;
let b = a;
a = 1;
What happens to b? Answer: Its value is 0.
To work around this we need some way of modifying the value instead of replacing it. Unfortunately, "primitive types" (strings/numbers/booleans etc.) cannot be modified in javascript. There are types that can be modified however, such as objects. You could solve this by wrapping your variables in an object called "env".
let env: {
CONSTANT_1: process.env.CONSTANT_1,
CONSTANT_2: process.env.CONSTANT_2
}
modules.exports = { env }
and then to modify:
env.CONSTANT_1 = "new value"
and to access:
if (!env.CONSTANT_1) { ... }
While answering a question I attempted to implement a setup where the main thread joins the efforts of the CommonPool to execute a number of independent tasks in parallel (this is how java.util.streams operates).
I create as many actors as there are CommonPool threads, plus a channel for the main thread. The actors use rendezvous channels:
val resultChannel = Channel<Double>(UNLIMITED)
val poolComputeChannels = (1..commonPool().parallelism).map {
actor<Task>(CommonPool) {
for (task in channel) {
task.execute().also { resultChannel.send(it) }
}
}
}
val mainComputeChannel = Channel<Task>()
val allComputeChannels = poolComputeChannels + mainComputeChannel
This allows me to distribute the load by using a select expression to find an idle actor for each task:
select {
allComputeChannels.forEach { chan ->
chan.onSend(task) {}
}
}
So I send all the tasks and close the channels:
launch(CommonPool) {
jobs.forEach { task ->
select {
allComputeChannels.forEach { chan ->
chan.onSend(task) {}
}
}
}
allComputeChannels.forEach { it.close() }
}
Now I have to write the code for the main thread. Here I decided to serve both the mainComputeChannel, executing the tasks submitted to the main thread, and the resultChannel, accumulating the individual results into the final sum:
return runBlocking {
var completedCount = 0
var sum = 0.0
while (completedCount < NUM_TASKS) {
select<Unit> {
mainComputeChannel.onReceive { task ->
task.execute().also { resultChannel.send(it) }
}
resultChannel.onReceive { result ->
sum += result
completedCount++
}
}
}
resultChannel.close()
sum
}
This gives rise to the situation where mainComputeChannel may be closed from a CommonPool thread, but the resultChannel still needs serving. If the channel is closed, onReceive will throw an exception and onReceiveOrNull will immediately select with null. Neither option is acceptable. I didn't find a way to avoid registering the mainComputeChannel if it's closed, either. If I use if (!mainComputeChannel.isClosedForReceive), it will not be atomic with the registration call.
This leads me to my question: what would be a good idiom to select over channels where some may get closed by another thread while others are still live?
The kotlinx.coroutines library is currently missing a primitive to make it convenient. The outstanding proposal is to add receiveOrClose function and onReceiveOrClosed clause for select that would make writing code like this possible.
However, you will still have to manually track the fact that your mainComputeChannel was closed and stop selecting on it when it was. So, using a proposed onReceiveOrClosed clause you'll write something like this:
// outside of loop
var mainComputeChannelClosed = false
// inside loop
select<Unit> {
if (!mainComputeChannelClosed) {
mainComputeChannel.onReceiveOrClosed {
if (it.isClosed) mainComputeChannelClosed = true
else { /* do something with it */ }
}
}
// more clauses
}
See https://github.com/Kotlin/kotlinx.coroutines/issues/330 for details.
There are no proposals on the table to further simplify this kind of pattern.
I see this code for how create a table with closure
https://varomorf.wordpress.com/2014/09/22/update-jtable-using-groovy/
but now I need create a table with closure
but using a text title for create all closure variable
like this; this code get the table but using the last value of xbn in this case 4
theTable = table(){
tableModel(){
var1="fecha"
xbn=0
stx="date;product;quant;weight;price".split(";")
println it
while(xbn<4) {
closureColumn(header:stx[xbn], read:{it[stx[xbn]]}) ;xbn=xbn+1 }
}
}
normally my code without loop
look like this
theTable = table(){
tableModel(){
var1="fecha"
xbn=0
stx="date;product;quant;weight;price".split(";")
println it
closureColumn(header:"date", read:{it["date"]})
closureColumn(header:"product", read:{it["product"]})
closureColumn(header:"quant", read:{it["quant"]})
closureColumn(header:"weight", read:{it["weight"]})
closureColumn(header:"price", read:{it["price"]})
}
}
please help me
Most DSLs don't prevent you from using the regular groovy stuff. So you can iterate multipl times, but you have to name your closure loop vars (e.g. your outer loop is the tableModel and it's implicitly named it).
...
tableModel() { // it ->
...
"date;product;quant;weight;price".split(";").each { hdr -> // name the loop var
closureColumn(header:hdr, read:{it[hdr]})
}
...
}
...
Hi,
as far as I know, custom blocks in Blockly can be defined wether in JSON or in JavaScript, but how can a mutator be initialized in JavaScript?
with JSON:
Blockly.defineBlocksWithJSONArray([
{....
"mutator": "myMutatorName"
});
Then the Mutator_MIXIN must be defined and with Blockly.Extension.registerMutator('myMutatorName', Blockly.myMutator_MIXIN, null, null) the mutator is added to the Block.
with JavaScript:
Blockly.Blocks['blockName'] = {
init: function() = {
....
??? this.setMutator(???)???
};
}
So how can this be done in JavaScript?
Kind regards
a new one
I might be just a little bit late here, but I'll leave the answer anyway for those who need a bit more concrete example.
In JavaScript, you don't actually need to bind a mutator to your block, you just need to define mutationToDom() and domToMutation(xmlElement) functions, like so:
Blockly.Blocks['my_custom_block'] = {
init() {
// Define your basic block stuff here
},
// Mutator functions
mutationToDom() {
let container = document.createElement('mutation');
// Bind some values to container e.g. container.setAttribute('foo', 3.14);
return container;
},
domToMutation(xmlElement) {
// Retrieve all attributes from 'xmlElement' and reshape your block
// e.g. let foo = xmlElement.getAttribute('foo');
// this.reshape(foo);
},
// Aux functions
reshape(param){
// Reshape your block...
}
}
Blockly will automagically take care of the rest and allow you to treat your block as dynamic one.
And if you need to used Mutator Editor UI, you must define decompose(workspace) and compose(containerBlock) functions and call this.setMutator(...) to set which blocks are used in the Mutator Editor UI, like so:
Blockly.Blocks['my_custom_block'] = {
init() {
// Define your basic block stuff here
// Set all block that will be used in Mutator Editor UI, in this
// case only 'my_block_A' and
this.setMutator(new Blockly.Mutator(['my_block_A', 'my_block_B']));
},
// Mutator functions
mutationToDom() {
// Same as previous example
},
domToMutation(xmlElement) {
// Same as previous example
},
decompose(workspace) {
// Decomposeyour block here
},
compose(containerBlock) {
// Compose your block here
},
// Aux functions
reshape(param){
// Same as previous example
}
}
Hope that these short examples help someone :)
You have to declare how the xml is loaded to dom, and how it is saved to xml and redrawn. Also notice how it attaches a mutator to a block element in case that is the only part you need to reference a mutator already present.
init: initFunction (Like you have declared.)
mutationToDom: MutationToDom,
domToMutation: DomToMutation,
updateShape_: UpdateShape`
If all you require is to create a reference to a mutator then what you need is an element of this kind, which we will programatically create in a bit:
<mutation mutator_name="true"></mutation>
The following snippet is an example of the extra functions mutationToDom, DomtoMutation UpdateShape which attaches extra input conditionally. I have a block with a checkbox that when enabled, adds an extra input.
function MutationToDom() {
var container = document.createElement('mutation');
var continueOnError = (this.getFieldValue('HasCONTINUE') == 'TRUE');
container.setAttribute('continueOnError', continueOnError);
return container;
}
function DomToMutation(xmlElement) {
var continueOnError = (xmlElement.getAttribute('continueOnError') == 'true');
this.updateShape_(continueOnError);
}
function UpdateShape(continueOnError) {
// Add or remove a Value Input.
if (continueOnError) {
this.appendValueInput("CONTINUE_ON_ERROR")
.setCheck('CONTINUE_ON_ERROR');
} else {
if (this.childBlocks_.length > 0) {
for (var i = 0; i < this.childBlocks_.length; i++) {
if (this.childBlocks_[i].type == 'continue_on_error') {
this.childBlocks_[i].unplug();
break;
}
}
}
this.removeInput('CONTINUE_ON_ERROR');
}
}
If I have a function in SSJS and I want to pass one "firm" parameter and a list of others that can change, what's the best way to do that? With some kind of hashMap or JSON or something else?
for example given something like:
myfunction( code:string, paramList:??) {
// do stuff here
}
Basically the function will create a document. And sometimes I'll have certain fields I'll want to pass in right away and populate and other times I'll have different fields I will want to populate.
How would you pass them in and then parse out in the function?
Thanks!
Use the arguments parameter... In JavaScript you are not required to define any of your parameters in the function block itself. So, for example, the following call:
myFunction(arg1, arg2, arg3, arg4);
can legally be passed to the following function:
myFunction () {
// do stuff here...
}
when I do this, I usually place a comment in the parens to indicate I am expecting variable arguments:
myFunction (/* I am expecting variable arguments to be passed here */) {
// do stuff here...
}
Then, you can access those arguments like this:
myFunction (/* I am expecting variable arguments to be passed here */) {
if (arguments.length == 0) {
// naughty naughty, you were supposed to send me things...
return null;
}
myExpectedFirstArgument = arguments[0];
// maybe do something here with myExpectedFirstArgument
var whatEvah:String = myExpectedFirstArgument + ": "
for (i=1;i<arguments.length;i++) {
// now do something with the rest of the arguments, one
// at a time using arguments[i]
whatEvah = whatEvah + " and " + arguments[i];
}
// peace.
return whatEvah;
}
Wallah, variable arguments.
But, more to the point of your question, I don't think you need to actually send variable arguments, nor go through the hassle of creating actual JSON (which is really a string interpretation of a javascript object), just create and send the actual object then reference as an associative array to get your field names and field values:
var x = {};
x.fieldName1 = value1;
x.fieldName2 = value2;
// ... etc ...
then in your function, which now needs only two parameters:
myFunction(arg1, arg2) {
// do whatever with arg1
for (name in arg2) {
// name is now "fieldName1" or "fieldName2"
alert(name + ": " + x[name]);
}
}
Hope this helps.
I would do this with a JSON object as the second parameter...
function myfunction(code:String, data) {
// do stuff here...
var doc:NotesDocument = database.CreateDocument();
if(data) {
for (x in data) {
doc.replaceItemValue(x, data[x]);
}
}
// do more stuff
doc.save(true, false);
}
Then you call the function like this:
nyfunction("somecode", {form:"SomeForm", subject:"Whatever",uname:#UserName()});
Happy coding.
/Newbs
I don't think that is possible in SSJS. I think the best option you have is to pass a hashmap or your own (java) object. I think a custom java object would be the nicest option because you can define some 'structure' on how your function can process it. A hashmap can be easily extended but it is not easy if you have a lot of code that create a lot of different hashmap structures...