How to Convert a String to a Constant in Ruby

Ruby: Convert Constant to String

You can't pass constants, you can only pass objects. If you pass FOO::BAR to a method, you're not passing the constant, but the object that has been assigned to FOO::BAR, i.e. the hash.

In order to retrieve the constant's name an object has been assigned-to from the object itself, the object has to store the name somehow.

Modules do store the constant name they have been assigned-to (Ruby sets the name when a module is assigned to a constant for the first time). And because FOO is a module (classes are modules), you can call FOO.name and it returns "FOO". But that only works because the object "knows" its name.

From the built-in objects, only Module (and therefore Class) has a name method that works this way.

You could add a name method to the hash instance FOO::BAR is referring to, although this is probably not what you want:

def (FOO::BAR).name
'FOO::BAR'
end

FOO::BAR.name #=> "FOO::BAR"

Another way is to pass both, the constant (the object actually) and its module to a method:

def find_const(mod, obj)
mod.constants.find { |c| mod.const_get(c).equal?(obj) }
end

find_const(FOO, FOO::BAR) #=> :BAR

The method traverses the module's constants and returns the (first) constant that refers to the passed object.

Set a constant value from a string

Use const_set:

class Rating
RATINGSCODES = %w{ G A AB TR P }

RATINGSCODES.each do |code|
const_set code, code
end
end
#=> ["G", "A", "AB", "TR", "P"]

p Rating::G
#=> "G"

How to convert Array of Constants into String with the constant names and not its assigned values

Store the constant names as strings, when you want to check the constant value use `#constantize'...

ABC = 'abc'
DEF = 'def'
GHI = ''
XYZ = 'anything'
LIST_ALL = %w(ABC DEF GHI XYZ)

Then you can do...

LIST_ALL.reject{|c| c.constantize.blank?}.join(', ') # => "ABC, DEF, XYZ"

:symbol to Constant in rails

class Symbol
def to_c
self.to_s.camelize.constantize
end
end

:monkey.to_c

Updated for Rails >= 4

As of Rails >= 4 .classify is better to use than .camelize

# .camelize with singular and plural symbols/strings
:user.to_s.camelize.constantize
# => User
:users.to_s.camelize.constantize
# => NameError: uninitialized constant Users

# .classify with singular and plural symbols/strings
:user.to_s.classify.constantize
# => User
:users.to_s.classify.constantize
# => User

Symbols as constants in Ruby

let defines a method with the name you pass to it. So, in your first example, you define a method named stack_overflow and you call it in your string interpolation.

In your second example, you define a method named STACK_OVERFLOW, but you do not call that method! STACK_OVERFLOW is dereferencing a constant, if you want Ruby to treat it as a method call, you have to make it obvious that it is a method call by either adding a receiver or an argument list or both (since only method calls can have a receiver or an argument list):

puts "Stack Overflow is helpful: #{self.STACK_OVERFLOW}"
puts "Stack Overflow is helpful: #{STACK_OVERFLOW()}"
puts "Stack Overflow is helpful: #{self.STACK_OVERFLOW()}"

String constants in Ruby

I'm not aware of any string constants like that in Ruby, but you could specify a range of characters to achieve the same thing:

>> ('A'..'Z').to_a.join("")
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
>> ('0'..'9').to_a.join("")
=> "0123456789"


Related Topics



Leave a reply



Submit