关于ruby中常数的澄清
我正在尝试构建一个rest客户端,由于很多操作几乎都是相同的,我想我应该将这些操作放入一个模块中,然后扩展该模块以获得这些操作集,并通过将它们定义为常量来保持唯一位的分离,相同的常量,但每个路由的设置不同,因此最终结果是不同的URL,但相同的操作关于ruby中常数的澄清,ruby,constants,Ruby,Constants,我正在尝试构建一个rest客户端,由于很多操作几乎都是相同的,我想我应该将这些操作放入一个模块中,然后扩展该模块以获得这些操作集,并通过将它们定义为常量来保持唯一位的分离,相同的常量,但每个路由的设置不同,因此最终结果是不同的URL,但相同的操作 module Common def list "some_url/#{Route_Name}.json" end end class Posts extend Common Route_Name = '
module Common
def list
"some_url/#{Route_Name}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
Comments.list
#=> "some_url/comments.json" what I expect to be outputted
但它只是错误,在本例中,它将出错未初始化常量Common::Route\u Name
我怎样才能让Route\u Name
成为我期望的样子
编辑:
我通过将
Route\u Name
更改为@Route\u Name
解决了这个问题,但问题是Route\u Name
是常量,它永远不会更改,因此使用实例变量感觉不对劲,即使它确实有效。我做了类似的事情,我定义了几个控制器操作(索引、创建等…)在一个模块中,然后将MyModule包含在我想要使用它们的控制器中
此时,在我的模块中,我可以调用self.controller\u name
,以了解我的实际来源
因此,您可以使用类似于
self.controller\u Name.tableze
或self.class.tableze
的方法来派生路由名称,而不是试图设置路由名称,在这里我定义了几个控制器操作(索引、创建等)在一个模块中,然后在我想要使用它们的控制器中包含MyModule
此时,在我的模块中,我可以调用self.controller\u name
,以了解我的实际来源
因此,您可以使用类似于self.controller\u Name.tableze
或self.class.tableze@Route\u Name
的东西来派生它,而不是试图设置路由\u Name
,正如您所提到的那样,它是一个实例变量,可以工作,但我认为您实际上要查找的是@@Route\u Name
,它将请将其设置为类级变量(每个类一个,而不是每个实例)。@route\u name
正如您所提到的是一个实例变量,可以工作,但我认为您实际要查找的是@@route\u name
,它将使其成为类级变量(每个类一个,而不是每个实例)
module Common
def list
"some_url/#{const_get('Route_Name')}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
Comments.list # => "some_url/comments.json"
@mtamhankar在从类名派生路由方面有一个很好的观点
改为使用const\u get
。这是一个方法调用(与按静态名称查找相比)。这意味着它将从祖先层次结构的底部开始常量查找
module Common
def list
"some_url/#{const_get('Route_Name')}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
Comments.list # => "some_url/comments.json"
@mtamhankar在从类名派生路由方面有一个很好的观点
ruby方法从该方法的所有者
中查找常量,而不是从接收方或接收方的类中查找常量。当您访问常量时,ruby解释器会沿着调用模块或类的模块嵌套查找常量
X = 0
module A
X = 1
module B
p Module.nesting #=> [A::B, A]
X = 2
def self.x
X
end
end
end
A::B.x # Try commenting out any 'X = ?' to see the difference
当调用A::B.x
时,ruby尝试在命名空间A::B
中查找常量x
(即尝试查找A::B::x
),如果找到,它将停止查找并立即返回该值。如果未找到,ruby将尝试在A
中查找X
,如果仍然没有找到,ruby将尝试在顶级命名空间中查找X
,即对象
由于类和模块有一个class/module方法name
,该方法返回类/模块的名称,因此您可以像下面这样重构公共
模块:
module Common
def list
"some_url/#{name.downcase}.json"
end
end
并消除所有Route\u Name='xxx'
ruby方法从该方法的所有者
查找常量,而不是从接收方或接收方的类。当您访问常量时,ruby解释器会沿着调用模块或类的模块。嵌套
查找常量
X = 0
module A
X = 1
module B
p Module.nesting #=> [A::B, A]
X = 2
def self.x
X
end
end
end
A::B.x # Try commenting out any 'X = ?' to see the difference
当调用A::B.x
时,ruby尝试在命名空间A::B
中查找常量x
(即尝试查找A::B::x
),如果找到,它将停止查找并立即返回该值。如果未找到,ruby将尝试在A
中查找X
,如果仍然没有找到,ruby将尝试在顶级命名空间中查找X
,即对象
由于类和模块有一个class/module方法name
,该方法返回类/模块的名称,因此您可以像下面这样重构公共
模块:
module Common
def list
"some_url/#{name.downcase}.json"
end
end
并首先按名称空间(大致:嵌套它们的位置)然后按祖先(继承的内容)删除所有Route\u Name='xxx'Ruby。因为list
是在Common
中声明的,所以查找从Common::Route\u Name
开始,不能再进一步了
但是,当调用list
时,它会在Comments
或Posts
上被调用,允许您通过self
访问这些内容。您可以使用self::Route\u Name
在需要的地方开始查找,而不是让Ruby自己查找常量本身
module Common
def list
"some_url/#{self::Route_Name}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
puts Comments.list #=> some_url/comments.json
puts Posts.list #=> some_url/posts.json
Ruby首先按名称空间(大致是:嵌套它们的位置),然后按祖先(继承的内容)。因为list
是在Common
中声明的,所以查找从Common::Route\u Name
开始,不能再进一步
但是,当调用list
时,它会在Comments
或Posts
上被调用,允许您通过self
访问这些内容。您可以使用self::Route\u Name
在需要的地方开始查找,而不是让Ruby自己查找常量本身
module Common
def list
"some_url/#{self::Route_Name}.json"
end
end
class Posts
extend Common
Route_Name = 'posts'
end
class Comments
extend Common
Route_Name = 'comments'
end
puts Comments.list #=> some_url/comments.json
puts Posts.list #=> some_url/posts.json
G