Q:

Dynamically create static variables in a class

I have the following class:
class A
  X = %w(a b c)
end

How can I create a list of static variables for class A using the values in X so that I will end up with the same thing as:
class A
  a = 1
  b = 2
  c = 3
end

I found out that methods can be defined with define_method, but I don't quite have a clue on how to do this for variables.

A:

Unfortunately, what you want is AFAIK impossible. You simply cannot introduce local variables into a scope dynamically. You might be tempted to do something like this:
class A
  X = %w(a b c)
end

class A
  bnd = binding

  X.each.with_index(1) do |var, i|
    bnd.local_variable_set(var, i)
  end
end

But that won't work. When you use local_variable_set to create a new variable, that variable will only exist within the Binding object, not in the scope from which the Binding was created.
class A
  bnd = binding

  X.each.with_index(1) do |var, i|
    eval("#{var} = #{i}", bnd)
  end
end

This won't work either. In fact, it is simply equivalent to the first.
Okay, so you think: "let's not use a Binding, then, just plain eval":
class A
  X.each.with_index(1) do |var, i|
    eval("#{var} = #{i}")
  end
end

Nope, this doesn't work either. The local variables still only get created inside the eval, but they don't leak outside. (They did leak in 1.8 and older, but they don't anymore in 1.9+.) And in fact, even if they did get created, they would get created in the scope of the block. So, you would have to use for/in instead.
Also note that even if you managed to inject local variables into the scope, they are still local variables: you cannot access them from anywhere else. (Unless you somehow manage to get hold of the Binding and call local_variable_get.)
It would make much more sense to make them methods, which is much easier:
class A
  X.each.with_index(1) do |var, i|
    define_singleton_method(:var) do i end
  end
end

Now, they can also be accessed from outside the scope:
A.a # => 1

or using the somewhat obscure method calling syntax using the scope resolution operator:
A::a # => 1

Of course, since they always return the same value anyway, why not make them constants?
class A
  X.each.with_index(1) do |var, i|
    const_set(var.upcase, i)
  end
end

A:

Constants are defined like this (they have to start with an uppercase letter):
class A
  A = 1
  B = 2
  C = 3
end

A::A #=> 1
A::B #=> 2
A::C #=> 3

To define them dynamically, use const_set:
class A
  %w(A B C).each.with_index(1) { |c, i| const_set(c, i) }
end

