Ruby/Reflection/method missing
Материал из Wiki.crossplatform.ru
Convert all system command to all class method
class CommandWrapper def method_missing(method, *args) system(method.to_s, *args) end end cw = CommandWrapper.new cw.date # Sat Apr 28 22:50:11 CDT 2001 cw.du "-s", "/tmp" # 166749 /tmp
Create a new class and override the method_missing method
class BackwardsString def initialize(s) @s = s end def method_missing(m, *args, &block) result = @s.send(m, *args, &block) result.respond_to?(:to_str) ? BackwardsString.new(result) : result end def to_s @s.reverse end def inspect to_s end end s = BackwardsString.new("I"m backwards.") # => .sdrawkcab m"I s.size # => 14 s.upcase # => .SDRAWKCAB M"I s.reverse # => I"m backwards. s.no_such_method # NoMethodError: undefined method "no_such_method" for "I"m backwards.":String
Create new method dynamically
class StringFactory def StringFactory.method_missing(m, *args) return String.new(m.to_s, *args) end end puts StringFactory.a_string # => "a_string" puts StringFactory.another_string # => "another_string"
If method does not exist, call the default one
class Library < Array def add_book(author, title) self << [author, title] end def search_by_author(key) reject { |b| !match(b, 0, key) } end def search_by_author_or_title(key) reject { |b| !match(b, 0, key) && !match(b, 1, key) } end :private def match(b, index, key) b[index].index(key) != nil end def method_missing(m, *args) search_by_author_or_title(m.to_s) end end l = Library.new("author","title") p l.a p l.b p l.c
Override method_missing method to provide meaningful error message
class Fixnum def method_missing(m, *args) if args.size > 0 raise ArgumentError.new("wrong number of arguments (#{args.size} for 0)") end match = /^plus_([0-9]+)$/.match(m.to_s) if match self + match.captures[0].to_i else raise NoMethodError. new("undefined method "#{m}" for #{inspect}:#{self.class}") end end end 4.plus_5 # => 9 10.plus_0 # => 10 -1.plus_2 # => 1 100.plus_10000 # => 10100 20.send(:plus_25) # => 45 100.minus_3 # NoMethodError: undefined method "minus_3" for 100:Fixnum 100.plus_5(105) # ArgumentError: wrong number of arguments (1 for 0)
Responding to Calls to Undefined Methods
class MyClass def defined_method "This method is defined." end def method_missing(m, *args) "Sorry, I don"t know about any #{m} method." end end o = MyClass.new o.defined_method # => "This method is defined." o.undefined_method # => "Sorry, I don"t know about any undefined_method method."