Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何创建类似“quot;的方法”;。通过“你某物”和“你某物”找到“你”;使用Ruby?_Ruby_Metaprogramming - Fatal编程技术网

如何创建类似“quot;的方法”;。通过“你某物”和“你某物”找到“你”;使用Ruby?

如何创建类似“quot;的方法”;。通过“你某物”和“你某物”找到“你”;使用Ruby?,ruby,metaprogramming,Ruby,Metaprogramming,使用Ruby,我知道你可以在命名方法时变得非常有创意。例如,在rails中,您有 我该怎么做 例如: def用5件东西获取个人信息 res=[] 每人| 如果person.number\u of_things==%神奇地从函数名中获取数字5% res您可以在缺少方法的情况下执行许多类似的操作: 你的例子让我有点困惑。如果在方法名称中使用硬编码的5来定义方法,则不需要在方法体中神奇地找到它。如果您想在缺少方法的情况下执行一些动态操作,应该是这样的: def method_missing(name

使用Ruby,我知道你可以在命名方法时变得非常有创意。例如,在rails中,您有

我该怎么做

例如:

def用5件东西获取个人信息
res=[]
每人|
如果person.number\u of_things==%神奇地从函数名中获取数字5%

res您可以在缺少方法的情况下执行许多类似的操作:


你的例子让我有点困惑。如果在方法名称中使用硬编码的5来定义方法,则不需要在方法体中神奇地找到它。如果您想在缺少方法的情况下执行一些动态操作,应该是这样的:

def method_missing(name, *args)
  if name.to_s =~ /get_persons_with_(\d+)_things/
    number_of_things = $1.to_i
    res = []
    persons.each do |person|
      if person.number_of_things == number_of_things
        res << person
      end
    end
    return res
  else
    return super(name, *args)
  end
end
  • super
    没有任何参数,只传递原始参数,无需显式传递
  • 早期
    返回
    由尾部
    if
    保护,除非
    表达式大大清除了控制流
  • 每个
迭代器所做的一切都是根据谓词选择项;但是,已经有一个迭代器用于选择项:
select

    Ruby有不同的元编程技术来完成这类工作

    首先,我们需要变量方法

    class DB
      def get_persons_with_x_things(x)
        res = []
        persons.each do |person|
          if person.number_of_things == x
            res << person
          end
        end
        return res
      end
    end
    
    方法u缺失 如果有无限多个x的
    方法_缺失
    将更适合此任务。如果有人试图调用一个不存在的方法,则执行
    method\u missing
    method\u missing
    的第一个参数是作为符号的方法名称,以下参数是原始参数

    class DB
      def method_missing(name, *args)
        case name.to_s
        when /^get_persons_with_(\d+)_things$/
          get_persons_with_x_things($1.to_i)
        else
          super(name, *args)
        end
      end
    end
    
    方法_丢失并发送 不使用静态regexe会更酷。但这可能会带来一些安全隐患。我在这里使用的方法
    send
    通过名称调用方法

    class DB
      def method_missing(name, *args)
        name.to_s=~ /\d+/
    # always be carefull with $ variables, they are global for this thread, so save everything as fast as you can
        new_name= "#{$`}x#{$'}"
        number= $1.to_i
        if method_defined?(new_name)
          send(new_name, number)
        else
          super(name, *args)
        end
      end
    end
    

    看看Ruby缺少的特殊方法。

    看来你已经得到了我想要的,谢谢!抱歉,如果不明显:)+1表示
    super
    。我讨厌调试只会吞噬方法的代码。顺便说一句:您可以使用
    inject
    而不是
    each
    和一个guard子句而不是
    if
    表达式来提高代码的可读性。上周我在编辑别人的代码时遇到了麻烦(尽管事实上它甚至不能像帖子那样工作),所以这次我要问:如果你同意的话,我会编辑你的帖子来表达我的意思。@Jörg当然,你可以编辑帖子。我只是想模仿@margg的例子,这样他就可以看到他的代码和我的答案之间的差异。我同意可以用更多的Ruby习惯用法来编写。
    class DB
      99.times do |i|
        define_method("get_persons_with_#{i}_things") do
          get_persons_with_x_things(i)
        end
      end
    end
    
    class DB
      def method_missing(name, *args)
        case name.to_s
        when /^get_persons_with_(\d+)_things$/
          get_persons_with_x_things($1.to_i)
        else
          super(name, *args)
        end
      end
    end
    
    class DB
      def method_missing(name, *args)
        name.to_s=~ /\d+/
    # always be carefull with $ variables, they are global for this thread, so save everything as fast as you can
        new_name= "#{$`}x#{$'}"
        number= $1.to_i
        if method_defined?(new_name)
          send(new_name, number)
        else
          super(name, *args)
        end
      end
    end