Using variables in modules

Can I define a variable in a module, and access and redefine it later?
Something like

module Gravity

G = 9.81

end

puts Gravity::G

Gravity::G = 9.8102 # we have done a more precise measurement

puts Gravity::G

works, but gives a warning. I have done some Google search and tried
instance and class variables for that module, but it does not work. My
goal: I have a module named Config with a configuration hash, with
predefined colors. I access that hash from other modules. That hash
should have default values, but it should be possible to redefine it.
(The other modules, which access that hash, are independent of each
other, none of then is special, so it is not really a good idea if one
of them has to define the initial hash content.) Currently I am using a
global variable for this purpose, called something like $Config_Colors.
Works fine, but I think I should use something related to my
configuration module, like Config::colors.

Best regards,

Stefan S.

On Sun, 2011-04-03 at 09:30 +0900, Stefan S. wrote:

Can I define a variable in a module, and access and redefine it later?

OK, this is very close to my desire:

module Gravity

#def initialize()
@g = 9.81
#end

def self.get()
@g
end

def self.set(g)
@g = g
end

end

puts Gravity::get()

Gravity.set(9.8102) # we have done a more precice measurement

puts Gravity.get()

This gives output
stefan@AMD64X2 ~/pet $ ruby hhh.rb
9.81
9.8102

Is there something like attr_accessor for modules, allowing writing
something like g=9.8102 and puts g instead of set and get methods?

Stefan S. wrote in post #990601:

I have a module named Config with a configuration hash, with
predefined colors. I access that hash from other modules. That hash
should have default values, but it should be possible to redefine it.

If you want to do this with a constant then you probably want
Hash#replace:

Config::Colors = {:red => 1, :blue => 2}
Config::Colors.replace({:red => 3, :blue => 4})

You’ll get no warning because the constant still points to the same
object, you’ve just mutated that object. But as others have said, a
class instance variable is probably cleaner.

Hash#merge is useful too when you have defaults, so unspecified keys
retain their default values:

def configure(settings)
Config::Colors.replace(Config::Defaults.merge(settings))
end

On Sun, 3 Apr 2011 09:30:28 +0900
Stefan S. [email protected] wrote:

Gravity::G = 9.8102 # we have done a more precise measurement

puts Gravity::G

works, but gives a warning.

You’re not defining a variable. You’re defining a constant with the
capital G. Use lowercases and this should work just fine.

On Sunday 03 April 2011 09:57:05 Stefan S. wrote:

puts Gravity::get()
Is there something like attr_accessor for modules, allowing writing
something like g=9.8102 and puts g instead of set and get methods?

You don’t need to use attr_accessor or attr_writer to define methods
ending
with an =:

module Gravity

@g = 9.81

def self.g= value
@g = value
end

def self.g
@g
end

end

If you want to use attr_accessor, you’ll need to do so from the
singleton
class of Gravity:

module Gravity

class << self
attr_accessor :g
end

end

I hope this helps

Stefano

On Mon, 2011-04-04 at 02:37 +0900, spiralofhope wrote:

You’re not defining a variable. You’re defining a constant with the
capital G. Use lowercases and this should work just fine.

I know.

Please note that lower case letter will not work in this context:

module Gravity
g = 9.81
end
puts Gravity::g
Gravity::g = 9.8102
puts Gravity::g

iii.rb:4: undefined method `g’ for Gravity:Module (NoMethodError)

Brian C. and Stefano C. already answered my question, thanks.

spiralofhope wrote in post #990694:

On Sun, 3 Apr 2011 09:30:28 +0900
Stefan S. [email protected] wrote:

Gravity::G = 9.8102 # we have done a more precise measurement

puts Gravity::G

works, but gives a warning.

You’re not defining a variable. You’re defining a constant with the
capital G. Use lowercases and this should work just fine.

Before handing out advice I suggest you test it first. Hint: if you just
change “G” to “g” in his original code, it will not work.