Why can I not concatenate two strings and assign them to a symbol?
-
21-08-2019 - |
Question
. . . as in this example:
helloworld.rb:1: syntax error, unexpected '=', expecting $end
:helloworld = "hello ".concat("world")
I thought if I use concat I'm modifying the string "hello " and adding "world" to it and then ultimately assigning the resulting string - "hello world" - to the :helloworld symbol on the left side of the equals sign. I thought that would be legal, just as if I had written:
:helloworld = "hello world"
oh, wait, that doesn't work either. (scratches head).
Solution
Try this:
:"hello world"
OTHER TIPS
Ruby symbols cannot have values assigned to them since they represent a canonical value. If you want to build a symbol from a string, you can use "hello ".concat("world").to_sym.
symbols are confusing when coming from languages that don't have anything like them. You can't assign to symbols, that's not what they're for.
Here are a couple of examples that may help explain it.
5.times do |i|
# a new string is created in each iteration of the loop
puts "my string".object_id
# there is only ever one symbol for each possible value
# so a new object is not created during each iteration
puts :my_symbol.object_id
# this often makes a difference when you're using them for things like hash keys
#some_method(:name => 'bob')
#some_method('name' => 'bob')
end
The other big difference is that a symbol comparison is simply a pointer comparison.
Perhaps what you're actually looking for is a constant? They can be dynamically generated, referred to later, and you get a warning if you try to reassign one.
>> HELLO_WORLD = "hello ".concat("world")
=> "hello world"
>> HELLO_WORLD = "foo"
(irb):3: warning: already initialized constant HELLO_WORLD
=> "foo"
You cannot assign to a symbol but you can return a symbol which is a concatenation of other symbols, although you have to pass through strings as far as I know (I'd like to know if there is a better way).
Suppose you want to obtain the symbol :myway
starting from the symbols :my
and :way
;
(:my.to_s + :way.to_s).to_sym # return :myway
Well, yeah. You can't assign to symbols. Do you mean something like:
foo = { :helloworld => "hello ".concat("world") }
?
class Symbol
def + (to)
return "#{self}#{to}".to_sym
end
end
This worked for me
@foo = 'world'
"hello #{@foo}".to_s.to_sym
output=> :"hello world"