Reputation: 23
I want to add new method to class String
, for example. But I don't want to make this change global (keeping classes clean is good, yes?).
So, instead of this code
class String
def is_palindrome?
self == self.reverse
end
end
module MyModule
class MyClass
def filter_palindrome(str_arr)
str_arr.select { |s| s.is_palindrome? }
end
end
end
I want to have something like this:
module MyModule
class String
def is_palindrome?
self == self.reverse
end
end
class MyClass
def self.filter_palindrome(str_arr)
str_arr.select { |s| s.is_palindrome? }
end
end
end
But, of course, it's not working (undefined method 'is_palindrome?' for :String
). So, is there any point in what I want? And if there is, what is the best way to achieve it?
Upvotes: 1
Views: 475
Reputation: 14082
If you are using Ruby 2.0, you can try refinements.
module MyModule
module StringAlter
refine String do
def is_palindrome?
self == self.reverse
end
end
end
end
using MyModule::StringAlter
module MyModule
class MyClass
def self.filter_palindrome(str_arr)
str_arr.select { |s| s.is_palindrome? }
end
end
end
If prior to Ruby 2.0, you cannot achieve this directly. Changes made to String will be global. However, instead of s.is_palindrome?
, why not write a helper method and call it like is_palindrome?(s)
. Then you don't have to reopen String
and you can restrict is_palindrome?
to be available only in some given scope.
This is the way Python does (self
), and so as to C# extension method.
Upvotes: 1