Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add method to base class in the context of module

I want to add a custom method to String class in Ruby. I am aware that it can be done with following code:

class String
  def my_own_method
    # impelementation comes here 
  end
end

If I write that code in a file say "string.rb" and somewhere else i.e. in irb, I write require "string" then it works quite fine and I have access to that custom method on any string object. However, the problem arises when I want to package my custom code into a module like this:

module A
  class String
    def my_own_method
      # implementation
    end
  end
end

Then when I include the module (with no error), I don't have access to the method on each string object unless I instantiate directly an string by calling, say,s = A::String.new. In that case I have access to my custom method but only for the s variable not on any string object. What shall I do to both package my util classes and automatically add their methods to base classes? Any help is really appreciated.

like image 475
Javad M. Amiri Avatar asked Jan 15 '23 05:01

Javad M. Amiri


2 Answers

One option is to use :: to ensure you are grabbing the top-level String class:

module A
  class ::String
    def my_own_method
      self.reverse
    end
  end
end

"some string".my_own_method # => "gnirts emos"

I also have to agree with Sergio's point at the end of his answer. Not really sure of the need to do this.

like image 134
BaronVonBraun Avatar answered Jan 20 '23 22:01

BaronVonBraun


Well, for one thing, you can use class_eval

module A
  String.class_eval do
    def my_own_method
      self.upcase
    end
  end
end


'foo'.my_own_method # => "FOO"

But if I were you, I'd go with opening a String class in the global scope (your first snippet). I don't really see the reasons not to do it.

like image 36
Sergio Tulentsev Avatar answered Jan 21 '23 00:01

Sergio Tulentsev