如何在 Ruby 中动态创建具有给定方法和方法体的类?

发布于 2024-12-18 01:33:06 字数 345 浏览 0 评论 0原文

在 Ruby 中,如何定义一个方法

def make_class(method_name, method_body, s_value)

返回一个类并执行以下实现

class Anonymous
    def method_name(args)
        method_body(args)
    end

    def to_s
       return s_value
    end
end

如果您可以链接到您发现对基本 Ruby 元编程有用的任何资源也很棒。

In Ruby how would you define a method

def make_class(method_name, method_body, s_value)

returning a class with the following implementation

class Anonymous
    def method_name(args)
        method_body(args)
    end

    def to_s
       return s_value
    end
end

If you can link to any resources you found useful on basic Ruby metaprogramming that would be great as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

朦胧时间 2024-12-25 01:33:06

您可以这样使用:

def make_class(s_value, method_name, &method_body)    
  Class.new do   
    define_method method_name, method_body    

    define_method :to_s do    
      s_value    
    end    
  end
end    

klass = make_class 'foo instance', :foo do |*args|    
  "called foo with #{args.inspect}"    
end    

k = klass.new     
puts k.to_s                 # => foo instance
puts k.foo [1, 2], 'hello'  # => called foo with [[1, 2], "hello"]

在这种情况下,您应该将方法的主体作为块传递(您可以将 |*args| 替换为您想要作为方法参数的任何参数列表)。如果您不想将 method_body 作为块而是作为字符串传递,那么 eval 就是您的朋友。

You can use smth like that:

def make_class(s_value, method_name, &method_body)    
  Class.new do   
    define_method method_name, method_body    

    define_method :to_s do    
      s_value    
    end    
  end
end    

klass = make_class 'foo instance', :foo do |*args|    
  "called foo with #{args.inspect}"    
end    

k = klass.new     
puts k.to_s                 # => foo instance
puts k.foo [1, 2], 'hello'  # => called foo with [[1, 2], "hello"]

In that case you are supposed to pass your method's body as a block (you can replace |*args| with any list of arguments you want to have as parameters for you method). If you want to pass method_body not as a block but as a string then eval is your friend.

怎言笑 2024-12-25 01:33:06
def make_class(method_name, method_body, s_value)
  Class.new {
    define_method method_name do |*args|
      eval(method_body)
    end

    define_method :to_s do
      s_value
    end
  }
end

《Ruby 元编程:像 Ruby 专业人士一样编程》 是一本非常好的书了解 ruby​​ 元编程。

def make_class(method_name, method_body, s_value)
  Class.new {
    define_method method_name do |*args|
      eval(method_body)
    end

    define_method :to_s do
      s_value
    end
  }
end

"Metaprogramming Ruby: Program Like the Ruby Pros" is a very good book to learn about ruby metaprogramming.

疯到世界奔溃 2024-12-25 01:33:06

我能想到的最简单的方法:

def make_class(method_name, method_body, s_value)
  klass = Class.new
  klass.class_eval "def #{method_name} ; #{method_body} ; end"
  klass.class_eval "def to_s ; #{s_value} ; end"
  klass
end

用法:

>> Anonymous = make_class(:foobar, "puts 'foo'", 23)
=> Anonymous
>> a = Anonymous.new
=> 23
>> a.foobar
foo
=> nil
>> a.to_s
=> 23

编辑:好的,我在这里有点太简单了,这不处理该方法的参数。

Easiest way I can think of:

def make_class(method_name, method_body, s_value)
  klass = Class.new
  klass.class_eval "def #{method_name} ; #{method_body} ; end"
  klass.class_eval "def to_s ; #{s_value} ; end"
  klass
end

Usage:

>> Anonymous = make_class(:foobar, "puts 'foo'", 23)
=> Anonymous
>> a = Anonymous.new
=> 23
>> a.foobar
foo
=> nil
>> a.to_s
=> 23

Edit: ok, I was a bit too simplistic here, this doesn't handle the args for the method.

单调的奢华 2024-12-25 01:33:06

我不建议这样做,但你可以......

def make_class(method_name, method_body, s_value)
  eval("
  class Anonymous
      def #{method_name}(args)
          #{method_body}(args)
      end

      def to_s
         return '#{s_value}'
      end
  end
  ")
end

make_class(:bla, :puts, 'bla')
Anonymous.new.bla('moin')
puts Anonymous.new.to_s

返回

moin
bla

i would not recommend doing this, but you could...

def make_class(method_name, method_body, s_value)
  eval("
  class Anonymous
      def #{method_name}(args)
          #{method_body}(args)
      end

      def to_s
         return '#{s_value}'
      end
  end
  ")
end

make_class(:bla, :puts, 'bla')
Anonymous.new.bla('moin')
puts Anonymous.new.to_s

returning

moin
bla
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文