@@ -405,6 +405,17 @@ def DelegateClass(superclass, &block)
405405 protected_instance_methods -= ignores
406406 public_instance_methods = superclass . public_instance_methods
407407 public_instance_methods -= ignores
408+
409+ normal , special = public_instance_methods . partition { |m | m . match? ( /\A [a-zA-Z]\w *[!\? ]?\z / ) }
410+
411+ source = normal . map do |method |
412+ "def #{ method } (...); __getobj__.#{ method } (...); end"
413+ end
414+
415+ protected_instance_methods . each do |method |
416+ source << "def #{ method } (...); __getobj__.__send__(#{ method . inspect } , ...); end"
417+ end
418+
408419 klass . module_eval do
409420 def __getobj__ # :nodoc:
410421 unless defined? ( @delegate_dc_obj )
@@ -413,18 +424,21 @@ def __getobj__ # :nodoc:
413424 end
414425 @delegate_dc_obj
415426 end
427+
416428 def __setobj__ ( obj ) # :nodoc:
417429 __raise__ ::ArgumentError , "cannot delegate to self" if self . equal? ( obj )
418430 @delegate_dc_obj = obj
419431 end
420- protected_instance_methods . each do |method |
421- define_method ( method , Delegator . delegating_block ( method ) )
422- protected method
423- end
424- public_instance_methods . each do |method |
432+
433+ class_eval ( source . join ( ";" ) , __FILE__ , __LINE__ )
434+
435+ special . each do |method |
425436 define_method ( method , Delegator . delegating_block ( method ) )
426437 end
438+
439+ protected ( *protected_instance_methods )
427440 end
441+
428442 klass . define_singleton_method :public_instance_methods do |all = true |
429443 super ( all ) | superclass . public_instance_methods
430444 end
0 commit comments