1

Ruby 1.9.3: I am trying to implement a method which takes as argument a class, a symbol and a proc and defines (eventually overwriting) a new instance method for that class, but not a class method so that this test should pass:

require 'test/unit'

include Test::Unit::Assertions

class String
  def my_method
    'my_method'
  end
end

def define_instance_method(klass, method, &block)
  # klass.send :define_method, method, &block
  # ...
end

define_instance_method(Object, :my_method) { 'define_instance_method my_method' }
define_instance_method(String, :my_method) { 'define_instance_method my_method' }

assert Object.new.my_method == 'define_instance_method my_method'
assert_raise(NoMethodError) { Object.my_method }

assert String.new.my_method == 'define_instance_method my_method'
assert_raise(NoMethodError) { String.my_method }

I did many tryings (define_method, define_singleton_method, class_eval, instance_eval, instance_exec, module_eval...) but with no success; do you have any ideas?

4

2 回答 2

3

@ProGNOMmers,回想一下 Ruby 中的对象是类,类是对象。

所以 Ruby 中的一切都是对象,甚至是类 :)

并且当您在其中定义一个方法时,Object它也可用于Class任何继承自Object.

这对所有班级都是如此。

一些证明:

define_instance_method(String, :my_method) { 'define_instance_method my_method' }

p String.new.my_method
p String.my_method

# =>  "define_instance_method my_method"
# =>  stackoverflow.rb:11:in `<main>': undefined method `my_method' for String:Class (NoMethodError)

看,你的方法还没有在里面定义Object,因此在里面不可用String

现在让我们这样做:

define_instance_method(Object, :my_method) { 'define_instance_method my_method' }

p String.my_method
# => "define_instance_method my_method"

p Array.my_method
# => "define_instance_method my_method"

p NilClass.my_method
# => "define_instance_method my_method"

因此,只需define_instance_method(Object...在您的测试
String规范中发表评论即可顺利通过。

以下是一些碰撞测试

于 2012-12-01T23:39:48.100 回答
0

class_eval 应该适合你。让我知道为什么它不适合你

class A
end

A.class_eval do
  define_method(:foo) {puts 'hello'}
end

A.new.foo #hello
A.foo     #NoMethodError: undefined method `foo' for A:Class
于 2012-12-01T23:51:52.927 回答