ruby - 为方法名动态生成前缀

标签 ruby metaprogramming dsl

假设我们有一堆带有典型前缀的方法。

def pref_foo
  # code
end

def pref_bar
  # code
end

我想了解如何自动将这些前缀添加到我的方法名称前(就像在 Rails 中的做法一样:Model.find_by_smth)。

换句话说,我想创建一些范围 pref_,它采用方法并将 pref_ 添加到它们的名称中,所以我的方法 foo 是以 pref_foo 的形式可用。


module Bar
  # definition of some wrapper `pref_`
end

class Foo
  include Bar

  <some wrapper from Bar> do
    def foo
      puts 'What does a computer scientist wear on Halloween?'
    end

    def bar
      puts 'A bit-mask.'
    end
  end
end

foo = Foo.new

foo.pref_foo # => "What does a computer scientist wear on Halloween?"
foo.pref_bar # => "A bit-mask."

最佳答案

试试这个,

class Module
  def with_prefix(prefix, &block)
    m = Module.new
    m.instance_eval(&block)
    m.methods(false).each do |name|
      define_method "#{prefix}_#{name}", &m.method(name)
      module_function "#{prefix}_#{name}" unless self.is_a?(Class)
    end
  end
end

class A
  with_prefix :pref do
    with_prefix :and do
      def foo
        puts "foo called"
      end

      def bar
        puts "bar called"
      end
    end
  end
end

A.new.pref_and_foo
A.new.pref_and_bar

这是如何工作的?

  • 我们在所有类的父类(super class)上定义一个新函数with_prefix
  • 这个函数接受一个名字和一个 block
  • 在匿名模块的上下文中评估 block 。
  • 这会在匿名模块而不是类上执行 def 语句
  • 枚举该模块的所有函数
  • 为每个函数创建前缀方法

关于ruby - 为方法名动态生成前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41341156/

相关文章:

ruby-on-rails - 捆绑抛出错误 Gem::Installer::ExtensionBuildError: ERROR: with Mavericks and ruby​​ 2.0

ruby-on-rails - 通过发送更新 ActiveRecord

c++ - decltype(function) 的类型是什么?为什么我不需要 "const"限定符?

haskell - 回合制游戏中用户可扩展移动效果的一般方法?

haskell - 如何解决 GADT 中的歧义

f# - 为 Microsoft 的 Luis 编写 F# Type Provider 的好方法是什么?

ruby - 匹配字符串的键数

ruby - 访问救援 block 中的错误消息

ruby - ERB#result 和 ERB#run 之间的区别

Ruby 元编程 - 不尝试评估内部 #{} 的多行字符串