当我的 AST 只是一个数组数组时,我应该使用访问者吗?
我见过用于遍历 AST 的访客模式。要使用此模式,您需要在 AST 节点对象上添加一个 accept(visitor)
方法。此方法调用visitor.visit(self)
,后者依次“处理”节点以获得所需的结果(例如,打印精美的 AST 版本)。
请注意,您通常必须修改节点本身才能添加该方法。但是,如果您的 AST 使用内置对象怎么办? Ruby 的 Ripper 库将 AST 作为数组数组返回。我可以添加 accept
方法,如下所示:
class Array
def accept(visitor)
visitor.visit(self)
end
end
查看 Array的文档,目前没有accept
方法,所以不会有冲突。但是,这对我来说不太合适,特别是如果我自己编写一个库的话。我不想“污染”其他人可能依赖的内置对象。
不过,这并不是 Ruby 独有的,因为我可以在 C# 中添加扩展方法来执行类似的操作。
我的问题是:在这种情况下我应该使用访问者模式,还是应该编写一个递归函数,只接受我正在处理的数据类型并返回我想要的答案?
I've seen the Visitor pattern used to walk an AST. To use this pattern, you add add an accept(visitor)
method on the AST node objects. This method calls visitor.visit(self)
which, in turn, "processes" the node to get the desired result (ex. a pretty-printed version of the AST).
Note, that you generally have to modify the nodes themselves to add the method. But, what if your AST is using built-in objects. Ruby's Ripper library returns an AST as an array of arrays. I could add the accept
method as follows:
class Array
def accept(visitor)
visitor.visit(self)
end
end
Looking at the documentation for Array, there is no accept
method currently, so there won't be a conflict. But, this doesn't quite feel right to me, especially if I'm writing a library myself. I wouldn't want to "pollute" a built-in object that others might be relying on.
This isn't unique to Ruby, though, as I could add an extension method in C# to do a similar thing.
My question is: should I be using the Visitor pattern in this scenario, or should I write a recursive function that simply takes in the data-type I'm working on and returns the answer I want?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
访问者模式是规避重复出现问题的已知解决方案(这里的问题可能仅适用于不提供
正如您所知,很多时候人们希望将数据结构与人们可能想要用它做的事情清楚地分开。
通常,您有一个类层次结构(具有不同类型节点的树)。然而,在这种情况下,我没有看到这种情况发生。所以我想知道为什么你首先要使用访客模式。创建将数组作为输入并处理它的不同类不是更容易吗?
The Visitor Pattern is a known solution to circumvent a recurrent problem (the problem here might be only applied to programming languages that do not provide multiple dispatch).
As you seem to aknowledge, many times one desires to clearly separate the data structure from what one might want to do with it.
Generally, you have an hierarchy of classes (a tree with different kinds of nodes). Yet, in this case, I don't see that happening. So I wonder why would you want to use the Visitor pattern in the first place. Wouldn't it just be easier to create different classes that take your array as input and process it?