class CAR
FORD = 1
GM = 2
BMW = 3
end
I want to create an array like:
all_cars = [CAR::FORD, CAR::GM, CAR::BMW]
=>[1, 2, 3]开发者_StackOverflow社区
Is there a way I can initialize this array with typing CAR:: for each element, something like
all_cars = %(FORD GM BMW).map {|ele| "CAR::" + ele}
=>["CAR::FORD", "CAR::GM", "CAR::BMW"]
Not want I wanted
Kind of like Phrogz answer, you could define the constants and initialize the array all at once like this:
class Car
MAKES = [
FORD = 1,
GM = 2,
BMW = 3
].freeze
end
That way, you'd have access to not only individual namespaced constants, but you have an array of them all, as a constant, without the need for repetition:
Car::MAKES # => [1, 2, 3]
Car::FORD # => 1
Don't forget the freeze
or people can mess with your array. You could always dup
it if you need to modify it within a particular operation.
Instead of creating an array of constants outside the class, I usually create such collections inside the class itself. In this case, you have no problem:
class Car FORD = 1 GM = 2 BMW = 3 MAKES = [ FORD, GM, BMW ] end p Car::MAKES #=> [1, 2, 3]
But if you are still set on doing what you propose, you want
Module#const_get
:all = %w[ FORD GM BMW ].map{ |k| Car.const_get(k) } #=> [1, 2, 3]
%w(FORD GM BMW).map{|x| CAR.class_eval(x)} # => [1, 2, 3]
or
%w(FORD GM BMW).map{|x| eval("CAR::#{x}")} # => [1, 2, 3]
This will do it using a module instead of a class:
module CAR
FORD = 1
GM = 2
BMW = 3
end
include CAR
CAR::FORD # => 1
CAR::GM # => 2
CAR::BMW # => 3
all_cars = [CAR::FORD, CAR::GM, CAR::BMW]
all_cars # => [1, 2, 3]
精彩评论