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

how to use symbols as variables

For general discussion related FlowStone

how to use symbols as variables

Postby Nubeat7 » Tue Oct 08, 2013 8:44 pm

i want to use the ruby value to send a lot of options to my knob so i packed all the options in a hash and send it to the knob - so how can i use just the symbol like ':sweepSize' instead of '@options[:sweepSize]'
in trogs shapemaker i saw a that getOptions methode but i couldn`t get it work like this in my example
Attachments
ruby_knob_3_0.fsm
(2.97 KiB) Downloaded 823 times
User avatar
Nubeat7
 
Posts: 1347
Joined: Sat Apr 14, 2012 9:59 am
Location: Vienna

Re: how to use symbols as variables

Postby Nubeat7 » Wed Oct 09, 2013 12:30 am

oh, found a solution to create instance variables from the optionshash, just asking myself if all this makes sense except of getting just one ruby value connection for all options, but when i create all the variables in every knob again, hmm

because the options panel could be used for all similar knobs - i normally use just 2 or 3 different knobs, and the idea was to get the option constants from one central point and not to create variables out of it in every knob:?
Attachments
ruby_knob_3_001.fsm
(2.94 KiB) Downloaded 838 times
User avatar
Nubeat7
 
Posts: 1347
Joined: Sat Apr 14, 2012 9:59 am
Location: Vienna

Re: how to use symbols as variables

Postby trogluddite » Wed Oct 09, 2013 1:05 am

The line...
Code: Select all
options_hash.each{|key,val| eval("@#{key}=val")}

...converts all hash entries into normal instance variables. e.g. options[:hello] creates an instance variable called @hello with the key's value assigned to it. The symbols can't be used directly in this case, so the little 'eval' trick is used to create normal instance variables.
EDIT) He he, you beat me to it! :D

Symbols are a rather strange kind of object - they don't "contain" anything, and can't be used as variables, only as values. They are closely related to Strings, but unlike a String they can never be edited, and have hardly any methods that you can use on them.
More importantly, there is only ever one instance of a symbol...
For example, @a = "Hello" and @b = "Hello", may look like the same String, but they are most likely two separate String objects being held in different places in the PC's memory - so you can edit them independently.
OTOH, @a = :hello and @b = :hello gives you two variables pointing at the same Symbol object, because there can only ever be one Symbol object called :hello - no matter where you put it in your code, a reference to :hello will always point at that same object.
That's why using Symbols can speed up 'if' and 'case' methods, and also Hash lookups. To check if two Strings are the same, Ruby has to check each and every letter. But Symbols are like class and method names - unique identifiers that the Ruby interpreter can replace with "ID codes". To compare two symbol references, Ruby just has to check "are these the same object" - there's no "content" to scan through, so it is much faster than Strings would be.
That might seem odd when you consider that Ruby is an interpreted language - surely it has to parse the letters anyway? But Ruby uses a much faster technique called a "Just In Time" (JIT) compiler - because methods usually get called many times, it only parses the text once, and then remembers the commands as "byte code"; just numbers that are much faster to run the second time around. As symbols can never be edited, they can also be encoded like this.

In fact, class and method names in Ruby code pretty much are Symbols - they all end up in the same 'library' that the Ruby interpreter uses for parsing the code. For example...
Code: Select all
String.instance_methods

...will produce an Array containing Symbols - each Symbol being the name of a method that you can use on String objects.
...or...
Code: Select all
@variable.respond_to?( :split )

...tells you whether or not the object in @variable has a method called 'split' - so true for a String, but false for an Integer.

So the best way to think of Symbols is just as 'labels' that you can 'tag' things with, like the keys of a Hash, or a selection that has been made (e.g. @current_state = :waiting .... if @current_state == :ready ...).
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: how to use symbols as variables

Postby Nubeat7 » Wed Oct 09, 2013 10:03 am

thanks trog for the explanation, so like in the optionpanel example for the knob, all the options are constants any way and do not change inside the knob code they just change when they are updated in the optionspanel (which only happens in FS), but when i understood right i only can use them like this @options[:sweepSize] (which doesnt make the code more beautiful :) ) without creating extra variables, what i wanted to avoid to save space and speed things up,

sure i could use a wireless input for each option, but if you want a second knob with different options you always have to rename 12 wireless options then and not just one options "bus",

so which way to go best?
User avatar
Nubeat7
 
Posts: 1347
Joined: Sat Apr 14, 2012 9:59 am
Location: Vienna

Re: how to use symbols as variables

Postby trogluddite » Wed Oct 09, 2013 7:28 pm

Well, you've pretty much hit on the reason that I convert the Hash contents into instance variables...

Speed
- Doing a Hash or Array lookup takes some time and processing, so if the Hash doesn't change very often, but you need to use the values a lot, it makes sense to move them to instance variables. And, like you say, it makes the code a hell of a lot neater!
If the Hash was constantly changing, this method wouldn't be very efficient, though. The 'eval' method is very greedy, because Ruby has to fire up the interpreter so that it can execute the commands in the string - in that case, you'd be better off just using regular Hash lookups.

Space
- This isn't such a big problem. Values of variables, or Hash/Array contents, are just stored as 'pointers' to the actual objects. When you do e.g. "@variable = my_hash[:index]", the only thing that gets copied is the pointer - which is just an integer number of a few bytes. The object itself doesn't get copied or touched at all - if you really did want a new copy of the object in memory, you would have to use the 'dup' (duplicate) or 'clone' methods. So Ruby is generally pretty "tidy" when you have code with lots of big objects, it will only use more memory if it really needs to.
Ruby also uses a 'garbage collector', so it regularly looks for objects that aren't being used any more, and destroys them to re-claim the memory. Of course, this uses bit of CPU power, so it's best not to create whole new objects unless you really need to.
The method '__id__' (that's two underscores each side) is very useful if you want to investigate this - you can use it on any object to find out its integer ID number, to easily see when Ruby is making a new object or not. Here's an example using '__id__' that demonstrates some of the principles of the 'pointer' style of Ruby variables...
Variables by pointer.fsm
(729 Bytes) Downloaded 868 times

So in the case of passing the options using a Hash, the only extra memory needed is a handful of bytes to store the collection of pointers - which is pretty good value when you consider the advantages of 'bussing' loads of values along a single connector, and having nice easy-to-debug readable code. Even more so if you are passing the same Hash to lots of controls that need the same options - all of the links and connectors will only be carrying a pointer to a single instance of the Hash.
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: how to use symbols as variables

Postby Nubeat7 » Wed Oct 09, 2013 10:12 pm

Thanks trog for the detailed explanation about this, big help in this confusing parts!
User avatar
Nubeat7
 
Posts: 1347
Joined: Sat Apr 14, 2012 9:59 am
Location: Vienna


Return to General

Who is online

Users browsing this forum: No registered users and 72 guests