可以定义一个函数的原型,或者以某种方式向Ruby表明函数是否存在,即使它尚未被定义?
我有很多这样的课程:
class Program
FIRST = Block.FIRST
FOLLOW = Set.new['$']
end
class Block
FIRST = Declaration.FIRST
FOLLOW = Set.new['.']
end
class Declaration
FIRST = ConstDecl.FIRST + VarDecl.FIRST + ProcDecl.FIRST
end
class ConstDecl
FIRST = Set.new['const'] + EMPTY_SET
end
你可以看到下面定义的类中的引用字段,有没有办法向Ruby表明这些类存在,并要求Ruby查找它们?
答案 0 :(得分:2)
我能想到的最简单的方法就是这样:
class Program
def self.first; Block.first end
def self.follow; Set.new['$'] end
end
class Block
def self.first; Declaration.first end
def self.follow; Set.new['.'] end
end
class Declaration
def self.first; ConstDecl.first + VarDecl.first + ProcDecl.first end
end
class ConstDecl
def self.first; Set.new['const'] + EMPTY_SET end
end
这对我来说似乎不是一个好设计,但是,我可能会创建这些对象而不是类,并使用适当的类型层次结构。
答案 1 :(得分:2)
Ruby和您可能习惯使用的其他语言(如C / C ++)之间的主要区别在于,在执行之前,C / C ++程序由编译器处理,该编译器将变量/函数的使用与其定义相匹配。 Ruby程序简单地从上到下执行,一次一个语句。因此,当执行引用Block.FIRST
的行时,Ruby解释器不能在程序代码中“向前看”并查看稍后将赋予Block.FIRST
的值。它对后来发生的事情一无所知;它只知道到目前为止已经执行了什么。
也许Ruby最强大的特性之一就是所有都是动态的,可以在运行时更改。如果您来自C / C ++背景,那么您需要首先了解Ruby。例如,Ruby中的常量可以有条件地分配:
class Block
if rand % 2 == 0
FIRST = '.'
else
FIRST = '$'
end
end
如果Ruby解释器需要“期待”以查看Block.FIRST
的值应该是什么,在上述情况下它应该预测什么?
这是对您习惯的概念转变,它将要求您以不同的方式构建您的程序,并以不同的方式思考您的程序。如果您尝试在Ruby中编写C / C ++ / Java,那么您将一直在战斗。
在这种情况下,我建议您只需颠倒定义的顺序并“自下而上”。还有其他方法可以达到相同的效果,但这是最简单的方法。
答案 2 :(得分:0)
您可以尝试defined?(function_name)