gpt4 book ai didi

使用 method_missing 的 Ruby 元编程来制作 HTML DSL

转载 作者:数据小太阳 更新时间:2023-10-29 08:37:59 26 4
gpt4 key购买 nike

我正在学习元编程,并且正在尝试制作一些 DSL 来生成 HTML。 @result 实例变量没有生成正确的答案,因为当调用 h1 方法时,@result 实例变量被重置。有没有一种优雅的方法来处理这些“嵌套”方法调用(我知道 Ruby doesn't technically have nested methods )。这是我的代码:

class HtmlDsl
attr_reader :result
def initialize(&block)
instance_eval(&block)
end

private

def method_missing(name, *args, &block)
tag = name.to_s
content = args.first
@result = "<#{tag}>#{block_given? ? instance_eval(&block) : content}</#{tag}>"
end
end

html = HtmlDsl.new do
html do
head do
title 'yoyo'
end
body do
h1 'hey'
end
end
end
p html.result # => "<html><body><h1>hey</h1></body></html>"
# desired result # => "<html><head><title>yoyo</title></head><body><h1>hey</h1></body></html>"

最佳答案

你的问题不在于 @result 被重置,只是你在 @result 中添加了 instance_eval(&block) 的返回值,这是 block 中的最后一行,而不是聚合 block 。这应该会更好(尽管不完美):

class HtmlDsl
attr_reader :result
def initialize(&block)
instance_eval(&block)
end

private

def method_missing(name, *args, &block)
tag = name.to_s
content = args.first
(@result ||= '') << "<#{tag}>"
if block_given?
instance_eval(&block)
else
@result << content
end
@result << "</#{tag}>"
end
end

现在:

html = HtmlDsl.new do
html do
head do
title 'yoyo'
end
body do
h1 'hey'
end
end
end
p html.result
#=> "<html><head><title>yoyo</title></head><body><h1>hey</h1></body></html>"

我所做的是,每个调用实际上都将一个片段呈现给@result,因此内部调用呈现内部片段,每个片段都用标签包装自己的内部片段.

关于使用 method_missing 的 Ruby 元编程来制作 HTML DSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23469834/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com