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

Alternative Ruby Event Dispatch

For general discussion related FlowStone

Alternative Ruby Event Dispatch

Postby trogluddite » Fri Oct 11, 2019 6:35 pm

If you have a Ruby primitive which has a lot of inputs, the 'event' method can sometimes get rather gnarly - it tends to end up becoming a very long chain of ifs and elsifs, or case clauses. If you use named inputs, which I would usually recommend to make re-ordering inputs easier and the code more readable, this also means that Ruby has an awful lot of String comparisons to do, which are never particularly efficient. So I thought I'd do a quick post on an alternative way of dispatching input events which can be both much tidier, and much more efficient if there are a lot of inputs.

This technique uses Ruby's send method, which provides an alternative way to call a named method...
Code: Select all
# A normal method call...
method_name(argument1, argument2, ...)

# The same method call using send...
send("method_name", argument1, argument2, ...)

As you can see, send takes as its first argument a String (or a Ruby Symbol) for the name of the method which you want to call, which you can then follow with whatever arguments the method requires. The handy thing is that the method name doesn't have to be written literally into the code, it can come from a variable or Ruby expression.

The first argument to the 'event' method receives a RubyEditConnector object which contains both the index of the input and its name, which is cleverly programmed so that doing a comparison will check against whichever is most appropriate. However, it's also possible to extract the name as just a normal String (or the index as an integer).

Putting those two things together, an 'event' method can be written which sends incoming events to the right chunk of code by working in a different way than usual. For each input, a method is defined containing the code to execute for that input, and then the input connectors are given the same names as the corresponding methods; the event's value and timestamp can just be passed through as method arguments. The 'event' method then becomes just a single line...
Code: Select all
def event(connector, value, timestamp)
    send(connector.name, value, timestamp)
end

# Method to execute when an input named "input_one" is triggered...
def input_one(value, timestamp)
    # Code
end

# Method to execute when an input named "input_two" is triggered...
def input_two(value, timestamp)
    # Code
end

# etc...

Because method look-up uses a clever hashing algorithm written in compiled C code, matching the event name Strings to their methods is much faster than lots of separate String comparisons, and the separate method for each input can make it easier to use Ruby's exception handling for debugging.

It's not a universal solution, of course - for example; it's not so useful if there are only a few inputs, or when you have a lot of inputs which don't need to take any action (an empty method definition can be used if "no-op" inputs are exceptional cases). And, naturally, the input connectors must have names which are legal and unique Ruby method names. However, for handling large numbers of inputs which each need to perform a unique action, I've found it a very handy technique, which results in very readable code (and very easy to search if, like me, you edit long Ruby code in an external code editor).
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: Alternative Ruby Event Dispatch

Postby adamszabo » Fri Oct 11, 2019 7:07 pm

Very interesting, thanks!
adamszabo
 
Posts: 657
Joined: Sun Jul 11, 2010 7:21 am

Re: Alternative Ruby Event Dispatch

Postby RJHollins » Sat Oct 12, 2019 5:13 am

Thanks TROG for sharing and teaching something new [for me].

8-)
RJHollins
 
Posts: 1568
Joined: Thu Mar 08, 2012 7:58 pm


Return to General

Who is online

Users browsing this forum: No registered users and 67 guests