I've been with Ruby for about a year now and have a language question: are symbols necessary because Ruby strings are mutable and not interned?
In, say, Java, strings are immutable and interned. So "foo" is always equal to "foo" in value and reference and its value cannot change. In Ruby, strings are mutable and not interned, so "a".object_id == "a".object_id
will be false.
If Ruby had implemented strings like Java, symbols wouldn't be necessary, right?
As of Ruby 2.3 immutable String
s have been implemented optionally via the RUBYOPT
flag --enable-frozen-string-literals
i.e.
RUBYOPT=--enable-frozen-string-literals ruby /some/file
This will cause all String
literals (strings created using ""
, %q{}
, %Q{}
, or "#{}" styles) to become immutable. This feature is currently being considered as default for Ruby 3.0. Follow along with Feature#11473. This feature is also available on a file level rather than a global level as a "magic comment"
# frozen_string_literal: true
This will have the same impact as the RUBYOPT
version but will apply only to the specific file. (one other way is to interact with the VM directly RubyVM::InstructionSequence.compile_option = {frozen_string_literal: true}
)
Since this is optional obviously it can be turned on and off and will still be an option in 3.0 just defaulting to on instead of off. Mutable String
s can still be created using String.new
and Immutable String
s can be dup
ed to make their dup
counter part mutable. (Please Note above: interpolation "#{}"
creates a new Immutable string as well because of ""
)
All that being said it does not replace the need for Symbols
in ruby. First of all the underlying C
that powers ruby leverages Symbols
heavily via rb_itern
to handle references for things like method definitions (These have been titled "Immortal Symbols" and will never be GCed).
Additionally Symbols
like all things in ruby are their own Object
and have their own useful sets of functionality. Take Symbol#to_proc
for example. This originated as a monkey patch solution for syntactical ease and was consumed into core in 1.8.7. This style is highly encouraged and regularly leveraged by the ruby community as a whole. Please advise how you would suggest having degradation of this feature work with a String
instead of a Symbol
.
While Symbols
used to be considered somewhat "dangerous" (for lack of a better word) due to their internment and memory consumption in combination with the dynamics of ruby. As of Ruby 2.2 most Symbols
(see above) can be garbage collected i.e. symbols created inside of ruby through String
internment (#intern
, #to_sym
, etc.). (These have been coined "Mortal Symbols")
Minor caveats include things like
define_method(param[:meth].to_sym) {}
This seems like since it is calling to_sym
that it should be a "Mortal Symbol" but since define_method
calls rb_intern
to keep the method reference it actually will create an "Immortal Symbol"
Hopefully this run down helps explain the necessity of Symbol
in ruby not only from a developer standpoint but also the heavy usage as part of the C
internals of ruby's implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With