Used like this:
Or like this:
Or even with lists!
Just remember to use the primitive set block!
Here is a great example of the power of V2:
Then run this twice:
Used like this:
Or even with lists!
Just remember to use the primitive set block!
Here is a great example of the power of V2:
Nice.
I get this every time I try, except for the time right after I click OK/APPLY in the block dialog.
I think this is the wrong topic ;). In any case, I can't find the original topic (deleted?).
I too need to click OK/APPLY first. The first time after I import it it works, but then it stops working. Furthermore, when I select "result pic" and it errors, if I click "cancel" to saving it, Snap! tries one more time before giving up, which never happens with any other error.
no, the block was fine until I used the class vars.
I have now fixed multiple things: errors inside the c-slot show, a stupid mistake with tracking of changes which caused only one change to be synchronized is fixed, and I removed erroneous reshapes that caused it to fail with lists (don't ask why I had them, I made that part of the script a long time ago). Numbers 1 and 3 of these were both contributing to the problem you experienced (number 1 meant that the error message was wrong, should have been "expecting a list getting a text". This made debugging a challenge).
ok, is the script pic in the op also updated?
It is now! Also, I just made yet another update to the block because of an additional bug I discovered. You may want to update anything you have saved.
Update: We now have single-variable class variables, which are much faster. However, as you nest them, they slow down to be slower than the variadic version!
I have also improved the variadic version, see the first post.
Are you able to explain to this muggle what this class variable thingy is?
I've tried analysing the code but it's well beyond my pay scale
And a practical use case?
Do you know about block variables?
Block variables lets you create a variant of script variables for a block: A script variable is created when a block is called, and it disappears when that call finishes. What if you want a variable that’s local to this block, as a script variable is, but doesn’t disappear between invocations? That’s a block variable. If the definition of a block includes a block variable, then every time that (custom) block is dragged from the palette into a script, the block variable is created. Every time that copy of the block is called, it uses the same block variable, which preserves its value between calls. Other copies of the block have their own block variables.
(quote from manual)
The way you access block variables is through this menu, gained by right clicking the definition hat:
I'm pretty sure the intended use case was to create hat blocks that only trigger once when the condition is true and then wait until the condition is false again:
FYI, since the recent addition of event hats, this particular use has been deprecated.
.
.
Now, many people (including myself) think/thought that block variables would be shared across all instances of the same block. When I learned that this was not the case, I was disappointed that I could not do some of the things I wanted to (see use cases below). So, I made it myself!
Use case 1:
Have you ever needed to run a script to set up some kind of library (whether using the extension load block or otherwise), but you don't really want to have to have a specific "load extension" block that has to run before anything else? You might have added the "load extension" block to every block that needs it loaded. But you're really just wasting computing time loading it over and over and over again, so you really need to know whether the extension has been loaded or not. Hmm... Maybe we could use block variables to store the data of whether or not the extension has been loaded. Oh. Wait. Nevermind. That will mean that the extension will still be loaded once for every block that uses the "load extension" block! Oh, well, it's better than nothing. But wait! With Class Variables, we can store whether or not the extension has been loaded and only load it ONCE. Yay!
Use case 2:
Computing data ahead of time and using the same data each time can be a lot faster than crunching the numbers over and over again. @sathvikrias has already tried using Class Variables to speed up their "blockspec" block, which loads information off the web to determine which blocks correspond to what blockspec. By only loading this once and storing it in a "Class Variable", performance increases dramatically.
There's probably more uses, but I think you get the picture.
naming idea: these variables are basically global variables that are just only accessible in the block, so maybe call them something like global variables? (or global script variables? global block variables? etc...)
That's one use case, but a simpler one is a counter:
Each time you drag the COUNTER block into a script, you're creating a counter. Each time that instance of COUNTER is actually called, the count increases by 1.
I thought of that, but I guess that it doesn't actually feel like a use case to me... Why does one need a counter that behaves in this way?
Another example, an object made using block variables:
the has _ changed?
predicate was actually my guiding idea behind block variables.
It needs to be threadsafe, so to avoid race conditions among parallel processes that each call it. A block definition variable ("class" is really something else, I think) would be shared by all instances and fail miserably. Therefore the programmer would have to make a global variable (either global global or sprite-local, which is sorta global as well) for every process / script.
Yeah, I'm not set on the name. But "class" was the initial proposed name, so I stuck with it. I like "block definition variable" better though, so I'll change it.
Oh yeah... I was meaning to mention that.
I'm really happy that the "block variable" feature unlocks the ability to do these "block definition variables" without any additional features! Whoopee!
Uh oh. I just realized that I didn't account for use cases like these. I can't very well leave the synchronization script running indefinitely, but there is no way to tell when the variable should persist or know when it changes... unless I modify the set and change (and certain list) primitives! I'll start working on that soon.
Well, for example, I use this counter to make gensyms (generated symbols):
What are those good for, you ask? One application is in writing a compiler, in which you turn
if condition then action
into
... compute condition into register r8
...
JMPZ R8, G781 ; jump if false (zero)
... do action
...
G781: ... continue