我有一个问题。我是Ruby的新手,所以我正在为一些问题而挣扎,这些问题我可以在几个小时后解决,但这个问题现在困扰了我一天。
我在/lib/math/calc.rb
中创建了一个包含以下内容的类:
module Math
module Calc
class << self
def check!(value1: nil, value2: nil)
raise Error.new(message: "value1 is required") unless value1
raise Error.new(message: "value2 is required") unless value2
Divide.send!(value1: :value1, value2: :value2)
end
end
end
end
然后我还有一个类Divide
,它位于:/lib/math/calc/divide.rb
,其含量为:
module Math
module Calc
class Divide
class << self
def send!(value1: nill, value2: nill)
# More code here
end
end
end
end
end
现在当我打电话:Math::Calc.check!(5, 5)
,我得到以下错误:
NameError: uninitialized constant Math::Calc::Divide
我已经尝试插入require 'divide'
,但那些导入不存在,他说。
我到底做错了什么?
3条答案
按热度按时间4nkexdtk1#
在Rails中,autoloader具有以下根目录:
/app
的任何子目录。/app/controllers/concerns
/app/models/concerns
根目录(又名自动加载路径)是自动加载程序将查找根级常量的目录。
因此,您可以通过将代码移动到现有根目录中来“修复”问题。
但是由于常量
Math
已经是Ruby核心的一部分,引用可能实际上不会导致自动加载器加载常量。这可能会给经典的自动加载器带来问题,但不会给Zeitwerk带来问题,Zeitwerk有常量的Map。如果你想用一个非常有问题的添加来monkeypatch一个核心类,你应该认真考虑这里(不要这样做)。一般来说,如果它不是你的名字空间,让你的肮脏的小nubbies远离。/lib
是故意不自动加载的。我们假设您在需要时会显式地要求代码在那里。如果您想将/lib
添加到eager和autoloading路径中,您可以这样做。然后真的有一个问题,这段代码只是奇怪和错误,只是不是Ruby。
如果要使关键字参数成为必需参数,请将其设置为必需参数:
但是不清楚为什么你甚至想在另一端使用关键字参数。在函数式函数中除法的元数总是2(
divide(x, y)
),而在面向对象的方法中是1(x.divide(y)
)。虽然使用关键字通常比使用大量的位置参数要好--如果你给它们起一个没有意义的名字,你会使代码变得不必要的冗长,并且更难实际使用。但最终这段代码是非常非rubyeske的,因为在Ruby中,通过向对象发送消息
:/, number
来执行诸如除法之类的操作。这将调用Integer上的方法
/
。如果你想探索如何实际编写一个计算器,我会写这样的东西:
一个三个三个一个
c9qzyr3d2#
如果你想用普通的Ruby来做,你只需要在你的模块中有
Divide
文件,这样解释者就知道文件的位置了文件树:
除此之外:注意,这里没有定义
Error
类,也没有向Divide.send!
发送正确的值。要做到这一点,应该发送Divide.send!(value1: value1, value2: value2)
cedebl8k3#
也许试试下面的。
库/数学/计算rb
库/数学/计算/除法. rb
此外,还可以在应用程序中创建lib目录,例如
app/lib