Basic metaprogramming: extending an existing class using a module?

I want part of my module to extend the String class.

This does not work

module MyModule class String def exclaim self << "!!!!!" end end end include MyModule string = "this is a string" string.exclaim #=> NoMethodError 

But it does

 module MyModule def exclaim self << "!!!!!" end end class String include MyModule end string = "this is a string" string.exclaim #=> "this is a string!!!!!" 

I do not want all other MyModule functions to be marked in String. Turning it on again at the highest level seems ugly. Is there really an easier way to do this?

+7
source share
2 answers

The exclaim method in your first example is defined inside a class called MyModule::String , which has nothing to do with the standard String class.

Inside your module, you can open the standard String class (in the global namespace) as follows:

 module MyModule class ::String # 'Multiple exclamation marks,' he went on, shaking his head, # 'are a sure sign of a diseased mind.' — Terry Pratchett, "Eric" def exclaim self << "!!!!" end end end 
+25
source

I'm not sure I understood your question, but why not open a line in a file, say exclaim.rb, and then request it when you need it:

exclaim.rb

  class String def exclaim self << "!!!!!" end end 

and then

 require "exclaim" "hello".exclaim 

But maybe I missed something?

+1
source

All Articles