Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

NEW REGISTRATIONS - please contact us if you wish to register on the forum

Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright

Ruby Execution Order Experiment

For general discussion related FlowStone

Ruby Execution Order Experiment

Postby trogluddite » Wed Nov 21, 2012 12:15 am

While working on some biggish Rubies, I've been scratching my head trying to prevent "no method for nil class" errors at startup. There are quite a few things that have to happen when a Ruby starts - loadState, fetching the stored input/output variables, the 'init' method etc.
So I devised a little test to see if I could work out once and for all what order these things happen...
Execution Order.fsm
(425 Bytes) Downloaded 1097 times

Each section declares a variable, and also watches the values of all the other variables to work out which ones it is able to see - they'll return 'nil' if not declared yet. The results I get seem to indicate that the order is...

1) - Parse the code to make all the method definitions. Code not wrapped in a method will also get executed.
2) - The 'init' method will run if there is one
3) - loadState retrieves any variables stored at the last schematic save.
4) - The input and output variable arrays are read
5) - The bare code is parsed again! (Note how it seems to see all of the other variables - yet all of the other stages can see the "bare" variable. Two passes of the parser is the only reason I can think of for this)
6) - The rest of the schematic goes 'live', and events at the inputs start arriving.

Hopefully this knowledge will prevent so many load time errors due to undeclared variables being used too soon - e,g, don't refer to an input variable within the 'init' routine etc.
I'd be glad to hear from anyone who can spot any errors in my reasoning, though, as I'm still not 100% that I'm reading the results quite right!

PS) I'd also be glad of any explanation why I called the input variable 'doodad' instead of just plain old 'input'!! ;)
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby Execution Order Experiment

Postby unkargherth » Wed Nov 21, 2012 2:19 am

Are you concious of what this means?

Yeah, well, Deeper knowledge, less bugs, etc, etc....

The only important thing is :

"Attention Citizen Trogluddite: By your actions, knowledge,expertise, generosity and easy paced way of sharing your knowledge, you, personally, without any doubt, declared yourself ( and worst, everybody agrees) as THE Ruby Component Resident Guru - from now RCRG - , receiving all the prestige and influence related to the position and assuming, knowing it or not, all the responsability this position implies, including , but not limited too:

.- Being requested for help
.- Being cited as the ultimate source of all wisdom
.- Becoming Master, Teacher and inspiration for the rest of us
.- Becoming the author of the next "Ruby for Flowstone for dummies"
.- Becoming the author of the next "Ruby for Flowstone: The Reference "
.- Becoming the author of the next "Ruby for Flowstone: The Hidden Chapters"
.- Becoming the author of the next "Ruby for Flowstone: What you always wanted to know and Never asked"
.- Becoming the author of the next "Ruby for Flowstone: What they don't want you to know"
.- Beign forced to write tons of free ( a free Beer) mistake-less, bug-free, eco-green, feature-full, resource-low, near Goodlike code, and
.- Accept our Thanks as one-and only payment for all of it

Thanks Citizen Trogluddite. Good work. Continue that way
"
Free your memory, .. with a free(). Like a pointer
Cast a pointer into an integer and it becomes the integer...
Cast a pointer into a struct and it becomes the struct...
A pointer can overflow... or can crash...
Be a pointer my friend
unkargherth
 
Posts: 29
Joined: Fri Apr 08, 2005 9:46 pm

Re: Ruby Execution Order Experiment

Postby trogluddite » Wed Nov 21, 2012 9:59 am

ROFL :D
I shall get my crayons out and make myself a special badge! ;)
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby Execution Order Experiment

Postby trogluddite » Wed Nov 21, 2012 8:23 pm

Been pondering this issue more since doing my experiments - and it has occurred to me that IF I have read the system right, it is a little flawed. (if I got it wrong, then my apologies for time wasting!!)
'init' seems to be executed before either the saved 'loadState' or input arrays have been read, so this means that the 'init' routine does not have access to any of those variable values.
This means that 'constants' cannot be derived from any of those values - for example, you might want to calculate a value or fill an array using an equation that requires the routine to know several 'property' values that the user sets up as 'user preferences' from the properties panel.

So this leaves us with three options for calculating 'derived' constants...
1) Waste CPU calculating them repeatedly whenever they are needed within the events section.
2) Have a special events routine triggered by a separate input and an 'After Load' primitive - which seems an unnecessary complication (though required for certain memory hungry data anyway e.g. bitmaps)
3) Just use bare code, not wrapped in a method, as this will get processed by the 'second pass' of the parser. Which kind of defeats the object of having an 'init' routine at all. This method has proved to be the most reliable for me in a couple of Rubies that I have written.

Here's a little example to show what I mean...
error no_error.fsm
(336 Bytes) Downloaded 1097 times

When you load it, notice how the one with the 'init' routine gets the length of the string wrong - it seems to know that the input is of the String class (so no Type error), but the value read is wrong because @input hasn't been read yet. But the version that is just bare code gets it right.

This seems odd - loading stored 'loadState' and input values is not going to need access to variables initialised in the 'init' routine, whereas 'init' having access to stored variables seems like it could be rather useful.

You might say - "well if that is the case, just don't use 'init' then!". Quite so - but there might be times where having 'init' is useful - there may be other circumstances where it would be useful to call it, for example; apart from which, it does make the code more readable, and could be handy when searching the code in an external editor.

This might seem a moot point when you can use 'saveState', 'loadState' and the input arrays to hang onto whatever values you need - but there are quite a few object classes that cannot be stored this way. To be able to do this, the class must have the correct methods defined for the Marshal module.. Not all of them have this, and user defined classes certainly will not unless the user builds them. There are also some data types are inherently not save-able (e.g anything that refers directly to an object's ID code, such as Proc objects).

This is of course quite 'power user' stuff, likely to be of concern to only a small minority - but if the example of SM is anything to go by, FlowStone will end up getting used in ways that DSPr never dreamed of (I hope so!). So it seems odd to process things in this order when there is no apparent disadvantage to doing it the other way around.
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby Execution Order Experiment

Postby MyCo » Thu Nov 22, 2012 12:34 am

the "Init" method is the FS equivalent of the class constructor (I think it is even called directly from there). And knowing nothing about inputs sounds OK for a constructor.

But I would also wish there would be a more clever way in which the inputs get initialized.

Right now I don't work with Ruby. I reported several things to Malc, and he confirmed that he'll change that in the next update. So the Ruby behaviour will be a little bit different in the future. And for me it doesn't make sense to build workarounds for things that get fixed soon.
User avatar
MyCo
 
Posts: 718
Joined: Tue Jul 13, 2010 12:33 pm
Location: Germany

Re: Ruby Execution Order Experiment

Postby Tronic » Thu Nov 22, 2012 1:09 am

several things? they might know?
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: Ruby Execution Order Experiment

Postby unkargherth » Thu Nov 22, 2012 1:40 am

MyCo wrote:Right now I don't work with Ruby. I reported several things to Malc, and he confirmed that he'll change that in the next update. So the Ruby behaviour will be a little bit different in the future. And for me it doesn't make sense to build workarounds for things that get fixed soon.


What you mean soon? Isn't the update policy once a year?
Free your memory, .. with a free(). Like a pointer
Cast a pointer into an integer and it becomes the integer...
Cast a pointer into a struct and it becomes the struct...
A pointer can overflow... or can crash...
Be a pointer my friend
unkargherth
 
Posts: 29
Joined: Fri Apr 08, 2005 9:46 pm

Re: Ruby Execution Order Experiment

Postby trogluddite » Thu Nov 22, 2012 2:54 am

MyCo wrote:And knowing nothing about inputs sounds OK for a constructor.

Hmm, yes. I can see where you're coming from - but I think that putting Ruby inside the context of FS changes things a bit. The trouble is that some input values are dynamic (calls of a RubyEdit method, if you like), but others, like 'properties' settings are static, and I'd see those almost as arguments of the constructor, e.g....
RubyEdit.new (property1,property2..) (metaphorically speaking).
But of course, the FS input values don't make that distinction between dynamic and static values. So it seems to me that the stored input array should default to being available to the constructor - dynamic values are free to update the startup values any time they like, so I can't see what harm it would do, even though it is not strictly the 'Ruby ethos'.

More importantly, every effort needs to be made to make Ruby work inside FS without confusing people - and the current execution order makes it all too easy to generate errors due to undeclared variables. "This is the routine that only runs once at the start" is a lot easier for people to understand than the concept of a class constructor, especially as we never explicitly construct instances by calling "RubyEdit.new" ourselves.

Thanks for your comments BTW. I posted rather than hassling Malc again straight away precisely because I wanted a second opinion - especially from folks that understand Ruby a bit better than I do!

Anyhow - enough ranting for one day! I've exchanged e-mails with Malc a few times myself, and he has been very receptive regarding the niggles and suggestions that I've put forward - so the signs are good that our feedback will lead to some very useful changes for the first update. :)
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: Ruby Execution Order Experiment

Postby trogluddite » Thu Nov 22, 2012 3:58 am

unkargherth wrote:What you mean soon? Isn't the update policy once a year?

No,no. There are two different licences.
The cheaper one just buys you the software as it is - with that one you get no upgrades unless you decide to pay for them later.
But if you upgraded from SM, or paid the extra for the 'annual upgrade' thingy, you get incremental upgrades throughout the year whenever there's anything new from the dev's. And at the end of the year, you don't pay for another full licence, you just 'top up' your upgrade policy.
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK


Return to General

Who is online

Users browsing this forum: No registered users and 138 guests