Reputation: 451
As far as I understand, symbols are ways to reduce the memory footprint of strings. So functionally :firefox
should be equivalent to "firefox"
in all cases.
However, in some of the selenium bindings, this doesn't seem to apply.
https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings
driver = Selenium::WebDriver.for :remote, desired_capabilities: :firefox
If I replace :firefox
with "firefox"
in that call, I get an error. Is the symbol here actually something more than a slightly more memory efficient string?
Upvotes: 2
Views: 95
Reputation: 27207
String
s and Symbol
s in Ruby are never directly equal. The difference in class is important in more than one way, and
:my_label != "my_label"
However,
:my_label.to_s == "my_label"
A Ruby Symbol
is more efficient than a String
in a few ways, including:
A Symbol
hashes and compares faster, which helps when using as hash keys.
Multiple uses of the same Symbol
do not make copies of the internal data, but are just identical pointers to the same object in memory. This makes them memory efficient when you have a lot with the same value.
If a library, such as Selenium::WebDriver
makes use of a Symbol as a parameter, then you cannot always replace it with an equivalent string. Whether or not you can treat it like that depends on the specific library. It is relatively easy to cast Symbol
s to String
s and vice-versa, so a lot of libraries will do that cast for you. It is very common to have library code that does param = param.to_s
when it needs a String
param.
Casting from String
to Symbol
is less commonly found in library code, because for a long while Ruby would not garbage-collect unreferenced Symbol
objects - converting arbitrary String
values to equivalent Symbol
ones was a way of getting memory leaks (and a vector for an attacker to crash your program).
Upvotes: 3
Reputation: 33327
To see the difference between a string and a symbol, see the following irb transcript:
irb(main):007:0> "firefox"
=> "firefox"
irb(main):008:0> "firefox".to_sym
=> :firefox
irb(main):009:0> "firefox".class
=> String
irb(main):010:0> "firefox".to_sym.class
=> Symbol
Upvotes: 0
Reputation: 52357
Symbol is a data type.
Selenium::WebDriver.for
method accepts arguments, and probably expects the hash values to be symbols. I never worked with the class and don't know whether last argument to for
is a hash or kwargs, but you got the idea: datatype matters.
When you pass "wrong" data type, error is raised.
Upvotes: 2