Tinderbox Forum

Help with list.each inside an if() conditional

This code works:

$MyString=$Name;
$Path(children).each(x){$Name(x)=$Name(x).replace(“NN”,$MyString)}

The idea is you have a parent note that has some child notes that each have in their names the string ‘NN’ and I want to replace that part of the string with the name of the parent. So if I stick that in an edict, it runs fine.

However, I don’t want it hanging around because I need this done just once, when I create the parent note which inherits the child notes from its prototype. I create the note, setting the name at the time of creation. So, I put my code in this:

if(!$isPrototype)
{
$MyString=$Name;
$MyList=$Path(children);
$EdictDisabled=true;
$MyList.each(x){
$Name(x)=$Name(x).replace(“NN”,$MyString)};
}

The idea is that the parent note is created, inherits this edict, in an enabled state from its prototype, it runs exactly once and then is disabled. (I don’t want it running on the prototype all the time, hence the conditional.)

I’ve played around and played around with this and as soon as the .each loop is in the if conditional, the values that x takes seem to vary, and some operators work and some do not. It is as if the if conditional changes the scope or namespace in some way I do not understand.

Help, please. I’m open to doing it another way, but I’d also like to understand if there is some scope change with if() that I do not understand.

The attribute $IsPrototype begins with a capital letter. That might be an issue here. I’m not sure this is what you intend to do; I think perhaps you wanted to test $EdictDisabled. Note, though, that $EdictDisabled is inherited from the prototype.

The example above lacks a closing parenthesis for the if() statement.

I’m not sure, but I think that the edict may be run before the note is named. That wouldn’t be what you want.

Thank you for the help, Mark.

The if() conditional is being entered even with the misspelling of $IsPrototype. I know because commands prior to .each are occurring.

I think the test is the right one and in my testing, the edicts are definitely not firing too quickly to give me a problem–though I can see I might need a better approach.

It is the .each inside the if() that behaves variably depending on which operators are used inside the loop. I’ll have to give an example, which I’ll try if I cannot get it working when I try later today.

I cannot see that the if() conditional is missing a parenthesis unless I really misunderstand the syntax. I count two curly brace pairs, the outer for the if() and the inner for the .each. and it looks to me like the parentheses all pair up. However, one can go blind to one’s own code so easily, I might not be seeing it. You know the syntax better than anyone, I’ll be grateful for you pointing out what I’m missing.

I expect it’s just a paste error in your example. You wrote – schematized:

if(…) {

$MyList.each(x) {

}

The closing curly brace on the if() statement is absent. It’s probably in your code and just not pasted here.

Thanks again, Mark. After a lot of careful stepwise construction, this version works:

if !$IsPrototype {
$MyString=$Name;
$MyList=$Path(children);
$MyList.each(x){$Name(x)=$Name(x).replace("NN",$MyString)};$EdictDisabled=true;};

I’m really not sure what was wrong before, except that $IsPrototype had a lower case “i”. At any rate, I’ll briefly explain the purpose and why $EdictDisabled is effective. I want to create a note that is pre-populated with sub-notes that share its name. So I create a note, name it, e.g. “80”. Then I change its prototype to one that has sub-notes of the form “NNe”, “NNf”, and “NN”. These sub-notes are inherited and thus instantiated. The edict above is inherited at this point too. When it runs, it renames the sub-notes, then turns itself off. So the risk of the edict running too early is mitigated provided I name the parent note before I set its prototype.

Really, this exercise is an attempt to create what might be called an initializer or constructor method elsewhere. If there is a feature of Tinderbox that would be a better way to do this, in general, I’d be grateful to know.

Now, along the way I found some behavior I do not understand. Consider this note hierarchy:

100
	NNa
	NNb
	NNc

Rule for 100:

$MyString=$Name;
$MyList=$Path(children);
$Text=$Text+$MyList.each(x){x};

Result in $Text:

eacheacheach

How could “each” possibly be the value of x?

So I thought to coerce x to a string, just to be sure.

$MyString=$Name;
$MyList=$Path(children);
$Text=$Text+$MyList.each(x){x+" "}

Result: eacheacheach

I thought I’d make the assignment within the loop in case there was some scope issue.

$MyString=$Name;
$MyList=$Path(children);
$MyList.each(x){$Text=x+" "};

eacheacheach

At this point I noticed that “eacheacheach” also contains the word ‘ache’…

While I do not understand why these versions did not do what I expected, I’m even more surprised that either x or the result of evaluating the .each loop could be the string “each”.

each() doesn’t return a value. You want

. $MyList.each(x){$Text=$Text+x;}