I'd like part of my module to extend the String class.
This doesn't work
module MyModule
  class String
    def exclaim
      self << "!!!!!"
    end
  end
end
include MyModule
string = "this is a string"
string.exclaim
#=> NoMethodError 
But this 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 don't want all the other functionality of MyModule to be marooned in String. Including it again at the highest level seems ugly. Surely there is a neater way of doing this?
The exclaim method in your first example is being 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) like this:
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
                        I'm not sure I've understood your question but why don't open string in a file, say exclaim.rb, and then require it when you need it:
exclaim.rb
  class String
    def exclaim
      self << "!!!!!"
    end
  end
and then
require "exclaim"
"hello".exclaim
But maybe I'm missing something?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With