Skip to content

Instantly share code, notes, and snippets.

@pasberth
Created September 16, 2011 13:05
Show Gist options
  • Select an option

  • Save pasberth/1222076 to your computer and use it in GitHub Desktop.

Select an option

Save pasberth/1222076 to your computer and use it in GitHub Desktop.
オーバーロードっぽいことをする
# -*- coding: utf-8 -*-
def Object.defun(symbol, *signature, &blk)
instance_variable_set(:@overloaded_methods, {}) if @overloaded_methods.nil?
klass = self
unless @overloaded_methods.key? symbol
@overloaded_methods[symbol] = {}
# super()を使ったり、実際のメソッドと同じ挙動にするにはdefine_methodを使うしかないので
overload = Proc.new { |*args|
oms = klass.instance_variable_get(:@overloaded_methods)
sig = Signature.new(*args)
if oms[symbol].key?(sig)
klass.method(:define_method).call(symbol, oms[symbol][sig])
ret = method(symbol).call(*args)
klass.method(:define_method).call(symbol, overload)
end
ret
}
define_method(symbol, overload)
end
@overloaded_methods[symbol][Signature.new(*signature)] = blk
end
class Signature
def initialize(*signature)
@signature = signature.map { |klass|
klass.is_a?(Class) ? klass : klass.class
}
end
def [](index); @signature[index]; end
def hash; @signature.hash; end
def ==(obj); @signature == obj.instance_variable_get(:@signature); end
def eql?(obj); @signature == obj.instance_variable_get(:@signature); end
def to_s; "(#{@signature.join(', ')})"; end
end
class A
defun(:homu, String) { |str| puts "I'm homu(String)" }
defun(:homu, Array) { |array| puts "I'm homu(Array)" }
end
class B < A
defun(:homu, String) { |str| super(str) }
end
A.new.homu("")
A.new.homu([])
B.new.homu("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment