我试图使用名为subscriptions
的方法在CurrentPlan中调用CurrentPlan :: Subscription。我有2个文件。这是我的代码
current_plan.rb
require_relative 'current_plan/subscription'
class CurrentPlan
# Get all subscriptions through current_plan
def subscriptions
CurrentPlan::Subscription.all
end
end
current_plan = CurrentPlan.new()
current_plan.subscriptions
current_plan/subscription.rb
require_relative '../current_plan'
class CurrentPlan::Subscription
def self.all
%w[subscription_1 subscription_2 subscription_3]
end
end
我收到的错误。
<CurrentPlan:0x0000010191ebd0>
/Users/foobar/Sites/ruby_apps/current_plan.rb:18:in `subscriptions': uninitialized constant CurrentPlan::Subscription (NameError)
from /Users/foobar/Sites/ruby_apps/current_plan.rb:25:in `<top (required)>'
from /Users/foobar/Sites/ruby_apps/current_plan/subscription.rb:3:in `require_relative'
from /Users/foobar/Sites/ruby_apps/current_plan/subscription.rb:3:in `<top (required)>'
from current_plan.rb:14:in `require_relative'
from current_plan.rb:14:in `<main>'
答案 0 :(得分:2)
在current_plan/subscription.rb
中,更改为:
require_relative '../current_plan'
class CurrentPlan
class Subscription
def self.all
%w[subscription_1 subscription_2 subscription_3]
end
end
end
当Ruby甚至不知道CurrentPlan::Subscription
是什么时,感到困惑,试图解决CurrentPlan
...
另一种方法是将require
语句放在文件末尾的current_plan.rb
中(在类声明之后),在这种情况下你不需要修改subscription.rb
,但这可能会导致其他问题。
答案 1 :(得分:2)
这里有两个问题。首先,你是require
- 一个圆圈中的文件。如果从底部开始查看错误的回溯,则要执行的第一件事是调用require_relative 'current_plan/subscription'
。该文件的第一行是对require_relative '../current_plan'
的调用,这是已经在加载过程中的原始文件。
Ruby现在将尝试要求此文件,并将跳过对require_relative 'current_plan/subscription'
的调用,因为它识别出已经需要该文件(即使它尚未完成需要)。定义CurrentPlan
类是可以的,因为即使该方法引用了未定义的常量,它也没有被调用。当执行到达current_plan.rb
的最后两行时,它会创建一个CurrentPlan
实例,并尝试在其上调用subscriptions
。这是发生错误的地方,因为subscriptions
指的是尚未定义的CurrentPlan::Subscription
(我们仍然没有从require_relative
顶部的subscription.rb
调用返回}})。
仅当需要的文件是最初执行的文件时才会出现此问题,即在这种情况下,您运行$ ruby current_plan.rb
然后调用require 'current_plan'
(或require_relative
)。如果其他文件需要current_plan
,那么require_relative '../current_plan'
中的subscription.rb
将被跳过,因为Ruby会将该文件识别为已经被要求。
修复这个很简单,jut删除行
require_relative '../current_plan'
来自subscription.rb
。 (您可能需要确保current_plan.rb
以外的文件不要直接尝试subscriptions
。
修复会暴露其他问题。在尝试要求subscription
时,尚未定义班级CurrentPlan
,因此class CurrentPlan::Subscription
将失败。
有几种方法可以解决这个问题,最直接的方法是改变
class CurrentPlan::Subscription
...
end
到
class CurrentPlan
class Subscription
...
end
end
以便在尝试定义CurrentPlan
时确保定义Subscription
。另一种方法是将require_relative
中的current_plan.rb
的呼叫移至CurrentPlan
定义之下(甚至在其中)。
答案 2 :(得分:1)
试试这个:
module A
class Subscription
def self.all
puts "all method of Subscription"
end
end
end
class CurrentPlan
include A
def subscriptions
CurrentPlan::Subscription.all
end
end
current_plan = CurrentPlan.new()
current_plan.subscriptions # => all method of Subscription
答案 3 :(得分:0)
好吧,如果你想继承行为,只需使用......好吧,继承。但请注意,Ruby不支持嵌套类,比如Java。
如果需要,可以使用Inner类来扩展外部类:
class Outer
class Inner < Outer
def outer_method
my_outer_method("hey!")
end
end
def my_outer_method(foo)
puts foo
end
end
foo = Outer::Inner.new
foo.outer_method #<= "hey!"
foo.my_outer_method("hi!") #<= "hi!"
顺便说一下,这更简单。
您仍然可以考虑命名空间/模块,例如:
module CurrentPlan #this is your namespace
end
class CurrentPlan::Subscription #this is your class
end
subs = CurrentPlan::Subscription.new #this is your instance
虽然在Ruby中你不能拥有模块的实例(在这种情况下,无法实例化CurrentPlan)。但您可以使用extend包含模块的方法。
答案 4 :(得分:0)
这对我来说很有用!感谢大家的帮助
current_plan.rb
require_relative 'current_plan/subscription'
class CurrentPlan
def subscription
CurrentPlan::Subscription.new
end
end
current_plan = CurrentPlan.new
puts current_plan.subscription.all
current_plan/subscription.rb
class CurrentPlan
class Subscription
def all
%w[asd asdadsadasdas njasdnjasndjasd subscription_1 subscription_2]
end
end
end