2013-03-29 30 views
1

例如,我想向類String添加新方法。但我不想讓這種變化成爲全球性的(保持班級清潔是好的,是的?)。向模塊內的標準類添加方法

因此,而不是這個代碼

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 

我想有這樣的事情:

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 

但是,當然,它不工作(undefined method 'is_palindrome?' for :String)。那麼,我想要什麼?如果有的話,實現它的最好方法是什麼?

回答

1

如果您使用的是Ruby 2.0,則可以嘗試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 

如果在Ruby 2.0之前,您無法直接實現此目的。對字符串所做的更改將爲全局。但是,爲什麼不寫一個幫助器方法,而是像is_palindrome?(s)那樣調用它,而不是s.is_palindrome?。然後,您不必重新打開String,並且您可以將is_palindrome?限制爲僅在某個給定範圍內可用。

這就是Python的做法(self),以至於C#的擴展方法。

+0

細化似乎是事情。謝謝。 –