During the Tinderbox meetup when I demo'ed Captain's Log to that point, Michael Becker asked why I didn't use a function to create the various elements of the log, instead relying on "sandbox variables" ($MyString, $MyDate, etc.). The issue arises that those "$My..." sandbox variables are actually attributes that remain with the note.
They'll change every day with each month, so a given month container will only hold one day's sandbox variables, twelve notes' worth in a year, for however many years the log runs. But every day container creates a Midwatch entry using local variables, and there are 365 of those a year (366 for leap years) for however many years the log runs. Not a huge amount of data, but it's unnecessary if you use...functions.
Based on Michael's comments, I looked at using functions to create the Midwatch entry. I found it somewhat confusing and kept finding reasons to put it off. But after yesterday's success with the Agents, I figured I'd take another stab at functions. And since my mind works best first thing in the morning, that's what I've been doing (after my daily review) this morning.
I thought I'd try something simple first, and create a function that created a new day container in a month container. To keep it even simpler, I opened a new Tinderbox document, Function Test, to learn how to create one before I tried it in the log.
So in the new document I created a top level note and just called it Test Note Sandbox Variables (TNSV), and copied the $Edict from the p_Month container in Captain's log into the TNSV $Edict. Hit, "Run Now" in the Edict pane of the Action Inspector and it created a new note, "Wednesday, March 27, 2024" as expected.
This will be important in a moment.
I created a new note called Test Note With Function, and its $Edict would call whatever function I came up with instead of just creating a note with today's date as its name using sandbox variables.
So then I read the Help file in Functions, and the aTbRef main entry on Functions. A little intimidating.
First thing I had to do wast turn on the Library folder. Now, this isn't strictly mandatory, a function will run from anywhere it's created. But I'm trying to be a good little coder and do it right the first time.
What wasn't clear from the documentation, and still isn't, is whether the $Name of the function note is semantically relevant. I think it is, but you kind of define the function in the $Text of the note anyway, so I don't know if Tinderbox scans the $Text attributes of all notes looking for the keyword function, or if it looks at the $Name of the note to locate the function. In any event, I gave the $Name of the function note the name of the function I was defining, "MakeDay." (Functions should be named with verbs, as they do something.)
The first thing I tried, because I have to see what doesn't work to understand the documentation, was to just copy the $Edict into the function curly braces. (That probably doesn't make sense, but trust me, I seem to have to get things wrong in order to understand how to get them right.)
That looked like this:
function fMakeDay
{
$MyDate="today";
$MyString=$MyDate.format("W, L");
create($MyString);
}
Didn't work.
So I went back to aTbRef and read some more about functions. The first thing I noticed is that parentheses are always required. So the first line is wrong and should be function fMakeDay() with parentheses.
Didn't work.
Read some more at aTbRef. Function doesn't use arguments here. Name should be ok. I think it's defined correctly.
Then I got to variables.
Ok, I guess this makes sense. Maybe sandbox variables (My...) are inappropriate here, and it looks like you have to define your variables at the beginning like you do in Pascal. (I actually recall hearing about this in a meet-up where they introduced functions. But I didn't recall it until after this.)
So then I tried this:
function fMakeDay()
{
var:date vNow = date("today");
var:string vDay;
vDay=vNow.format("W, L");
create(vDay);
}
That didn't work either, first because I'd omitted the semi-colons after defining each variable. Duh.
Fixed that. Then something happened. I'd hit Run Now in the $Edict pane of the Test Note With Function, and something would happen, a new note would appear without a name and then disappear instantly.
Recall that TNSV, the first note, created a note named "Wednesday, March 27, 2024."
Because this is the first thing in the morning and my brain is working a peak efficiency, (It's all downhill from here.) I remembered that Tinderbox won't create two notes with the same name, unless you specify different paths.
I didn't want to screw around with paths for this simple test, so I tried this:
function fMakeDay()
{
var:date vNow = date("today");
var:string vDay;
vDay="Test"+vNow.format("W, L");
create(vDay);
}
And that worked!
And this blog post is just me documenting this to myself, because I'll try to do something in the afternoon and forget why this worked and the other thing didn't.
So, a few tips on functions:
1. Always include parentheses
2. Always define your variables
3. Don't forget to check for semi-colons.
Since a Library note (or any note, I guess) containing a function can contain more than one function, I guess I've just figured out that the $Name of the note isn't semantically relevant with regard to calling the function.
I don't know that I'm going to be creating a lot of functions, now that I kind of know how to, but I think I'll stick with one function per note, and give the $Name of the note the name of the function, just so I can keep things straight.
Time for a walk.
✍️ Reply by email
Originally posted at Nice Marmot 06:19 Wednesday, 27 March 2024