use*_*702 3 ruby dsl static-methods metaprogramming block
有没有办法可以像这样:
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
Run Code Online (Sandbox Code Playgroud)
进入这个:
(1..10).all? do |number|
((number * 2 * 5) / number) - 7 == 3
end
Run Code Online (Sandbox Code Playgroud)
?
我试图为每一种可能的方法定义方法(choose_one_from,then_multiply_it_by ......),它们接受一个参数并用它做一些事情,但是当产生块时它产生了值,但我真的不知道如何组合它们所以我可以得到第二段代码.
编辑:我觉得我必须做像DSL一样的东西
你会想要这样的东西:
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
Run Code Online (Sandbox Code Playgroud)
你可以在哪里使用它:
Mathisizer.when_i
.choose_one_from(1..10)
.then_multiply_it_by(5)
.did_you_get?(3)
Run Code Online (Sandbox Code Playgroud)
基本上,您将创建一个"构建器"对象,该对象提供用于创建数学运算对象的流畅API.