DSP-Robotron wrote:It's overloading something or crashing Ruby or something.
Exactly that - all three examples are overloading the Ruby interpreter. While they're all legal Ruby code, I wouldn't expect any of them to work in the context of FlowStone.
For the most part, Ruby components are expected to work like this...
- A value changes at one or more of the RubyEdit input connectors (an "event").
- This causes the code to be executed.
- One or more results are sent to the RubyEdit output connectors.
- (Optional: The code can schedule another "event" to happen at some later time).
- Code execution ends until the next "event".
- The new output values are now used by the rest of the schematic.
(NB: editing the code also triggers execution)
There's also another very important caveat - Ruby is a single-threaded scripting language and the interpreter is shared by the whole schematic. So only one Ruby "event" in one RubyEdit can be processed at a time. This isn't a problem so long as each event takes a limited amount of processing time - events are processed one after another fast enough that the results all arrive where they're needed at the appropriate time.
However, your examples each contain what is effectively an infinite loop. Once the code starts executing, there's never an "end of event". The Ruby interpreter is now totally consumed by executing the loop, so no further Ruby events can be processed, not by this RubyEdit, nor by any other. Within FlowStone, this is considered a fatal condition, and to protect against it, the RubyEdit will be disabled if there's no "end of event" after a few seconds (it can only be enabled again manually in the workspace). The non-Ruby parts of the schematic will continue running, but nothing meaningful will happen at the RubyEdit's outputs, as without an "end of event", the schematic is not told that anything might have changed. (NB: because the "end of event" is so necessary, even the "sleep" method counts as "hogging the interpreter").
To do what (I think) you want to do, you need the code to be only the "body" of your loops, and the looping to be done externally to this code by either...
1) ...using external components to trigger events at appropriate times (e.g. a "ticker" or "Frame Sync" primitive at a RubyEdit input).
2) ...having each event schedule the next one after an appropriate time delay (e.g. the "input" or "scheduleEvent" Ruby methods at the end of the code).
And one further note of warning! There is one very large problem that can happen with the Ruby "fuse". Due to the way that Ruby events are queued internally, when the "fuse" blows in one RubyEdit, it can also blow in other RubyEdits which have events scheduled to happen at the same time. If you get unlucky, this can kill unrelated RubyEdits all over a schematic at load-time, and it is a huge PITA to re-enable them all (you have to follow the modules with red borders). Always save your schematic before making any big changes to Ruby code!!
As you can see, using Ruby within FS is quite a bit different than using it as a stand-alone scripting language (and the documentation doesn't always do a very good job of explaining how!!)