【问题标题】:How can I generate code out of text in Ruby如何在 Ruby 中从文本中生成代码
【发布时间】:2013-12-23 17:53:28
【问题描述】:

有没有办法让我变成这样:

SomeModule.some_method do
  choos_one_from 1..10
  then_multiply_it_by 2
  then_multiply_it_by 5
  then_divide_it_by :picked_number
  then_subtract 7
  did_you_get 3
end

进入这个:

(1..10).all? do |number|
  ((number * 2 * 5) / number) - 7 == 3
end

?

我尝试为每个可能的方法(choose_one_from,then_multiply_it_by...)定义方法,这些方法接受一个参数并用它做一些事情,但是当 yield 块时它会产生值,但我真的不知道如何组合它们所以我可以得到第二段代码。

EDIT :我觉得我必须制作类似 DSL

的东西

【问题讨论】:

    标签: ruby metaprogramming block static-methods dsl


    【解决方案1】:

    你会想要这样的东西:

    module Mathisizer
    
      def when_i
        Mathisizer::Builder.new
      end
    
      class Builder
        attr_accessor :range, :choosen_number
    
        def new
          @operations = []
        end
    
        def choose_one_from(range)
          self.range = range
    
          # Randomly determine the number from the range
          # self.choosen_number = ...
    
          self
        end
    
        def then_multiply_it_by(n)
          @operations << MultiplicationOperation.new(n)
          self
        end
    
        def then_add(n)
          @operations << AdditionOperation.new(n)
          self
        end
    
        def did_you_get?(n)
          x = self.result
    
          x == n
        end
    
        def result
          x = choosen_number;
    
          @operations.each do |operation|
            x = operation.invoke(x)
          end
    
          x
        end
      end
    
      class BaseOperation
        def new(n)
          @number = n
        end
    
        def invoke(n)
          raise 'Base classes must implement invoke(n) -> number'
        end
      end
    
      class MultiplicationOperation < BaseOperation
        def invoke(x)
          return @number * x
        end
      end
    
      class AdditionOperation < BaseOperation
        def invoke(x)
          return @number + x
        end
      end
    
    end
    

    你可以在哪里使用它:

    Mathisizer.when_i
      .choose_one_from(1..10)
      .then_multiply_it_by(5)
      .did_you_get?(3)
    

    基本上,您将创建一个“构建器”对象,该对象为创建数学运算对象提供流畅的 API。

    【讨论】:

    • 但是,如果我不知道 'then_multiply_it', 'then_devide_it_by' 的顺序怎么办。我将如何在 Mathesizer.new 中进行正确的链接?
    • @user2128702 方法返回自我,所以顺序无关紧要
    • @GregBurghardt 那么,'self' 返回整个 Mathesizer 对象?
    • @GregBurghardt 我不认为我明白了。我只有一个乘数属性。如果我在其他操作之间很少有它们,我不知道如何分配它。如您所知,不同的操作有不同的优先级。
    • self 变量返回 Mathisizer 的实例。另外,我明白你对运算顺序的意思,这对数学来说有点重要。您可以维护一系列操作。每个操作都是它自己的类,每个操作类都包含一个通用接口。让我再想一想。
    猜你喜欢
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多