这是什么
Ruby 有时被描述为“一种易于编写 DSL 的语言”。
我总结了为什么说 Ruby 易于编写 DSL。
如果您有类似“也有这样的元素”之类的内容,如果您可以发表评论或提出编辑请求,我会很高兴。
DSL 示例
DSL 代表领域特定语言。
简而言之,就像“用户可以自由地实现和提供接近语法的机制”。
我会把详细的解释留给维基百科。
Ruby 和 Rails 中使用的著名 DSL 是围绕 ActiveRecord 的实现。
这是一个例子。
用户.rb
class User < ApplicationRecord
validates :name, presence: true
has_many :articles
end
这样,使用 Rails 的 ActiveRecord 特定语法,您可以轻松设置验证、设置关系等。
我将组织为什么可以在 Ruby 中实现这样的 DSL。
用于实现 DSL 的 Ruby 属性
Ruby 有一些在其他语言中很少见的属性。
我将描述它们的特点。
1.调用方法时()可以省略
Ruby 在调用方法时可以省略()
。
这允许您将方法调用编写为类似于语法声明的代码。
例子.rb
def hello(args)
"Hello #{args}"
end
hello 'world' #=> 'Hello world'
2.您可以将块作为参数传递
Ruby 允许在其他语言中使用块作为参数来定义方法。
有关其工作原理的详细信息,请参见下文
这使得实现涉及块表示法的代码变得容易,这通常只在其他语言的语法中可用。
例子是:
例子.rb
def two(&block)
.times do |i|
block.call(i)
end
end
two do |i|
puts "This is #{i+} times"
end
3. 在类声明块内直接执行方法
Ruby 允许在声明类时直接在类声明块内执行方法。
例如,以下代码可以正常工作。
例子.rb
class Base
class << self
def hello(arg)
pp "Hello #{arg}"
end
end
end
class Example < Base
hello 'world'
end
#=> 'Hello world'
4. 方法可以通过define_method等动态定义。
Ruby 可以使用define_method
、define_singleton_method
等动态声明方法。
这使得根据方法接收到的值在类中定义方法变得容易。
有关这些机制,请参阅以下文章。
例子.rb
def define_call(&block)
define_method :call do
block.call
end
end
define_call do
pp 'Hello world'
end
call #=> 'Hello world'
写一个 DSL
让我们使用排列的属性实际编写 DSL。
这一次,我实现了一个 DSL 来为方法设置时间限制。
例子.rb
require 'timeout'
class Timer
class << self
def timeout(t)
@@time = t
end
def process(&block)
define_method :call do
puts 'start'
Timeout.timeout(@@time) do
block.call
end
puts 'success'
rescue Timeout::Error
puts "timeout"
end
end
end
end
class Example < Timer
timeout
process do
sleep 0.5
end
end
Example.new.call
概括
通过这种方式,Ruby 的属性组合可以轻松实现专门用于特定领域的 DSL。
请尝试各种实现。
原创声明:本文系作者授权九品源码发表,未经许可,不得转载;
原文地址:https://www.19jp.com/show-308622228.html
版权声明:除特别声明外,本站所有文章皆是本站原创,转载请以超链接形式注明出处!