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] 'Watch' method explained
3 posts
• Page 1 of 1
[Ruby] 'Watch' method explained
I recently was asked about the 'watch' method, and I thought I could share some general info, that might be of interest for those, who just dive into the Ruby world.
The 'watch' method is not part of a standard Ruby install. It is a method especially created for use in Flowstone. I never had a look at Flowstone's source code, so my explanations are not about the exact inner working, but about the general principle.
1) It is a RubyEdit class instance method. Which means, every RubyEdit instance (the red windows) has its own, independent watch method.
2) It is expecting 1 or 2 arguments. If you pass only one argument, the first argument is derived from a default value and the second argument gets your passed argument assigned. Currently the default value for the first argument is a string with the content "Quick Watch". Here are some forms of usage:
watch() ##prints on the info pane: Quick Watch = nil (You passed no value, which is nil)
watch(1) ##prints on the info pane: Quick Watch = 1 (You passed one argument, which is assigned to argument 2)
watch(1, 2) ##prints on the info pane: 1 = 2 (You passed 1 as the first argument, 2 as the second)
4) If you already know hashes (if not, learn about them, quick), you will notice that the watch method pretty much acts like a hash. You pass it a key/value pair and it prints out the value of the key.
watch("key", "value") ## prints on the info pane: key = value
5) That can lead to mistakes. For example, if you use a key/value pair, and later use the same key with another value, the old value will be overwritten (since the key is the same)
watch("var", 1)
watch("var", 2)
It will now know var's value as 2, not 1 (and also not 1 and 2)
So, if you have a variable that you want to watch, but that variable will change its value, you should use a seperate key for the possible two values.
a = 1
watch("first a", a)
a = 2
watch("second a", a)
6) This is the most challenging point for people, who never programmed before, or only in very, very old languages. The watch method does not immediatly print on the info pane! Instead, it only updates its hash table, and waits for the full execution of the method, where you used 'watch' in. Only after the method returned is it that 'watch' actually prints out to the info pane. Please spare me to explain in detail, why this is so. Just accept it. Here's an image, that might make it more obvious:
So, what has happened here? The method consists of two parts.
The first part checks if a certain input was used to trigger an event, and orders 'watch' to print the input class on the info pane.
The second part is the mean thing. It is an endless loop. I purposely prevent the event method from returning. If you would execute that code (please don't, you have to close and restart Flowstone afterwards), you would see that the info pane stays clear. Then the Flowstone interrupt function breaks the code, returns from the method, writes the error message, and finally the watch hash table gets printed on the info pane. Exactly in this order.
Once again, no printing occurs, before the current method has returned! This also can let you run into issues. For example, if you run a method that uses the watch method and then calls another method, where another watch method call is made, the order will be reversed to what you'd expect. You will see the second method's watch result printed first (because this method has returned to method 1), then the first watch method's result. Take care of proper naming, to instantly see what you are presented with.
7) You can make good use of watch within a loop. It overwrites values only, if the key is the same. Here is some example code that will print ten values to the info pane (create a trigger input and name it "myinput"):
For longer iterations, you don't want to use watch like that, of course. Instead, you'd create an array or hash, fill it with whatever data you want to watch, and call the watch method after the loop has executed, with the array or hash as argument.
The 'watch' method is not part of a standard Ruby install. It is a method especially created for use in Flowstone. I never had a look at Flowstone's source code, so my explanations are not about the exact inner working, but about the general principle.
1) It is a RubyEdit class instance method. Which means, every RubyEdit instance (the red windows) has its own, independent watch method.
2) It is expecting 1 or 2 arguments. If you pass only one argument, the first argument is derived from a default value and the second argument gets your passed argument assigned. Currently the default value for the first argument is a string with the content "Quick Watch". Here are some forms of usage:
watch() ##prints on the info pane: Quick Watch = nil (You passed no value, which is nil)
watch(1) ##prints on the info pane: Quick Watch = 1 (You passed one argument, which is assigned to argument 2)
watch(1, 2) ##prints on the info pane: 1 = 2 (You passed 1 as the first argument, 2 as the second)
4) If you already know hashes (if not, learn about them, quick), you will notice that the watch method pretty much acts like a hash. You pass it a key/value pair and it prints out the value of the key.
watch("key", "value") ## prints on the info pane: key = value
5) That can lead to mistakes. For example, if you use a key/value pair, and later use the same key with another value, the old value will be overwritten (since the key is the same)
watch("var", 1)
watch("var", 2)
It will now know var's value as 2, not 1 (and also not 1 and 2)
So, if you have a variable that you want to watch, but that variable will change its value, you should use a seperate key for the possible two values.
a = 1
watch("first a", a)
a = 2
watch("second a", a)
6) This is the most challenging point for people, who never programmed before, or only in very, very old languages. The watch method does not immediatly print on the info pane! Instead, it only updates its hash table, and waits for the full execution of the method, where you used 'watch' in. Only after the method returned is it that 'watch' actually prints out to the info pane. Please spare me to explain in detail, why this is so. Just accept it. Here's an image, that might make it more obvious:
So, what has happened here? The method consists of two parts.
The first part checks if a certain input was used to trigger an event, and orders 'watch' to print the input class on the info pane.
The second part is the mean thing. It is an endless loop. I purposely prevent the event method from returning. If you would execute that code (please don't, you have to close and restart Flowstone afterwards), you would see that the info pane stays clear. Then the Flowstone interrupt function breaks the code, returns from the method, writes the error message, and finally the watch hash table gets printed on the info pane. Exactly in this order.
Once again, no printing occurs, before the current method has returned! This also can let you run into issues. For example, if you run a method that uses the watch method and then calls another method, where another watch method call is made, the order will be reversed to what you'd expect. You will see the second method's watch result printed first (because this method has returned to method 1), then the first watch method's result. Take care of proper naming, to instantly see what you are presented with.
7) You can make good use of watch within a loop. It overwrites values only, if the key is the same. Here is some example code that will print ten values to the info pane (create a trigger input and name it "myinput"):
- Code: Select all
def event(index)
if index == "myinput"
(0..9).each { |i| watch(i, "Yeah! #{i}")}
end
end
For longer iterations, you don't want to use watch like that, of course. Instead, you'd create an array or hash, fill it with whatever data you want to watch, and call the watch method after the loop has executed, with the array or hash as argument.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: [Ruby] 'Watch' method explained
Man, I appreciate you explaining WATCH, Tulamide.
It is something I've tried to use in tracking variables, outputs, etc. I admit that I've had struggle to get it working
at times [usually more times] ... my thought was as a tool to monitor Variable values.
But heck ... I had trouble getting it to display more than 1 variable at a time. [if it could].
Like I say, I was trying to use it as a type of 'variable dump' to confirm if my Ruby calculations were operating the
way I intended.
Needless to say ... I need to re-read your post above, and try out the examples to see if some of this can sink in.
Thanks again !
It is something I've tried to use in tracking variables, outputs, etc. I admit that I've had struggle to get it working
at times [usually more times] ... my thought was as a tool to monitor Variable values.
But heck ... I had trouble getting it to display more than 1 variable at a time. [if it could].
Like I say, I was trying to use it as a type of 'variable dump' to confirm if my Ruby calculations were operating the
way I intended.
Needless to say ... I need to re-read your post above, and try out the examples to see if some of this can sink in.
Thanks again !
- RJHollins
- Posts: 1571
- Joined: Thu Mar 08, 2012 7:58 pm
Re: [Ruby] 'Watch' method explained
Brilliant explanation tulamide and, oddly enough, exactly the problem I’m having at the moment
Can I ask please, does the same apply to the output method? In my tests output behaved the same way as watch (and similarly, not as I expected).
I personally really appreciate you posting such a detailed explanation for Ruby infants like me and it would be great if there was more to come.
Cheers
Spogg
Can I ask please, does the same apply to the output method? In my tests output behaved the same way as watch (and similarly, not as I expected).
I personally really appreciate you posting such a detailed explanation for Ruby infants like me and it would be great if there was more to come.
Cheers
Spogg
-
Spogg - Posts: 3358
- Joined: Thu Nov 20, 2014 4:24 pm
- Location: Birmingham, England
3 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 33 guests