我是Ruby新手,可能不懂基本的东西:
我正在尝试这个:
# lib/common_stuff.rb
module CommonStuff
def self.common_thing
# code
@x = second_thing # --> should access method in same module. Doesn't work.
end
def self.second_thing
# code
end
end
# app/controllers/my_controller.rb
require 'common_stuff'
class MyController < ApplicationController
include CommonStuff
y = self.common_thing # accesses the Module method -> works
end
错误:
NoMethodError(未定义的方法`second_thing'for MyController:0x000000088d8990):lib / common.rb:7:'common_thing'
我尝试了Module和实例方法。同样在Module中声明second_thing一个实例方法或两个方法作为实例方法都不起作用。我有什么误解?
**编辑更正**
我意识到我的错误是使方法类方法(使用self。前缀)。没有它它实际上是有效的。以为我试过了,但我一定是昨天失明了。所以工作代码是(只是一个构造的例子 - 通常我当然不会实例化控制器):
# lib/common_stuff.rb
module CommonStuff
def common_thing
@x = second_thing # --> access method in same module. Works now too.
end
def second_thing
10
end
end
# app/controllers/my_controller.rb
require 'common_stuff.rb'
class MyController
include CommonStuff
def a_class
y = common_thing # accesses the Module method -> works
puts y
end
end
ctrl = MyController.new
ctrl.a_class
答案 0 :(得分:-1)
我误解了什么?
1)@variable
是私有的,因此您始终需要提供访问方法来访问它(或使用instance_variable_get()
来侵犯隐私权):
module CommonStuff
def common_thing
@x = second_thing # --> should access method in same module. Doesn't work.
end
def second_thing
10
end
end
class MyController
include CommonStuff
attr_accessor :x
end
obj = MyController.new
obj.common_thing
puts obj.x
--output:--
10
2)您不能包含模块的类方法:
module CommonStuff
def self.common_thing
puts 'hello'
@x = second_thing # --> should access method in same module. Doesn't work.
end
def self.second_thing
10
end
end
class MyController
include CommonStuff
end
CommonStuff.common_thing
MyController.common_thing
--output:--
hello
1.rb:21:in `<main>': undefined method `common_thing' for MyController:Class (NoMethodError)
#obj = MyController.new
#obj.common_thing #Same error here
如果要将一些类方法注入MyController,则需要重新编写CommonStuff模块:
module CommonStuff
def self.included(includer) #Advanced 'hook' method
includer.extend ClassMethods
end
module ClassMethods
def common_thing
puts 'hello'
@x = second_thing # --> should access method in same module. Doesn't work.
end
def second_thing
10
end
end
end
class MyController
include CommonStuff
y = common_thing
puts y
puts instance_variable_get(:@x)
end
--output:--
10
10
每当模块被另一个类/模块包含时,都会调用hook方法,并将该方法作为参数传递给包含类/模块。
对通讯的回应:
只有控制器的实例变量才能在视图中使用,例如:
class MyController
def do_stuff
@x = 10 #instance variable
end
end
但在类方法中创建的@variables
不是控制器的实例变量:
class MyController
def self.do_stuff
@x = 10
end
end
因此,在类方法中创建的@variables
将无法在视图中使用。