views:

65

answers:

1

Greetings,

I want to tinker with the global memcache object, and I found the following problems.

  1. Cache is a constant
  2. Cache is a module

I only want to modify the behavior of Cache globally for a small section of code for a possible major performance gain.

Since Cache is a module, I can't re-assign it, or encapsulate it.

I Would Like To Do This:

Deep in a controller method...

code code code...

old_cache = Cache
Cache = MyCache.new

code code code...

Cache = old_cache

code code code...

However, since Cache is a constant I'm forbidden to change it. Threading is not an issue at the moment. :)

Would it be "good manners" for me to just alias_method the special code I need just for a small section of code and then later unalias it again? That doesn't pass the smell test IMHO.

Does anyone have any ideas?

TIA,

-daniel

+3  A: 

But you can overwrite constants in Ruby (regardless of whether it's a module or class or simple other object):

MyConst = 1

# do stuff...

old_my_const = MyConst
MyConst = 5
puts "MyConst is temporarily #{MyConst}"
MyConst = old_my_const

puts "MyConst is back to #{MyConst}"

Output:

a.rb:6: warning: already initialized constant MyConst
MyConst is temporarily 5
a.rb:8: warning: already initialized constant MyConst
MyConst is back to 1

The warnings are simply that: warnings. Your code will continue to run the same.

Okay, maybe the warnings are unacceptable in your situation for some reason. Use this suppress_all_warnings method I've written. Example includes reassigning a module.

def suppress_all_warnings
  old_verbose = $VERBOSE
  begin
    $VERBOSE = nil
    yield if block_given?
  ensure
    # always re-set to old value, even if block raises an exception
    $VERBOSE = old_verbose
  end
end

module OriginalModule
  MyConst = 1
end

module OtherModule
  MyConst = 5
end

def print_const
  puts OriginalModule::MyConst
end

print_const

suppress_all_warnings do
  old_module = OriginalModule
  OriginalModule = OtherModule

  print_const

  OriginalModule = old_module
end

print_const

Now you get the correct output, but without the warnings:

1
5
1
Mark Rushakoff
Ah, I see what was going on.I was trying to replace a Constant with an instance of a class, thus I was getting a "dynamic constant assignment" error.
Daniel