`
cookoo
  • 浏览: 648351 次
  • 性别: Icon_minigender_1
  • 来自: Shanghai
社区版块
存档分类
最新评论

Ruby的根模块命名空间

    博客分类:
  • Ruby
阅读更多
如果你要定制Rails的违例输出页面的话的,一般会用这样的代码:
class ApplicationController < ActionController::Base
  ...
  def rescue_action_in_public(exception)    
    case exception
    when ::ActionController::UnknownAction
      render_with_layout ....
    when ActiveRecord::RecordNotFound
       ...
    end
  end
end


这里唯一奇怪的地方就是::ActionController::UnknownAction, 为什么去掉开头的::就会报错说找不到UnknownAction?看看源码,UnknownAction类确实存在于ActionController模块中啊。

简单说,Ruby的namespace是从当前位置开始的找起的,而由::开头访问的是所谓根模块命名空间(root module namespace),好比绝对路径。为了便于理解,我们来看个例子:
class Obj
  def self.p
    "Obj"
  end
end
module Test
  class Obj
    def self.p
      "Test::Obj"
    end
  end
  class See
    def self.p
      puts Obj.p
      puts ::Obj.p
    end
  end
end

在irb中load这段代码,并执行
>> Test::See.p 
Test::Obj      
Obj

显然See看见Obj会首先在同一命名域下搜索。而外层的Obj是和Test同级别的所谓根命名,使用::才能直接引用以区别于Test内部的Obj。另外如果这时在See.p里面插一句pp Module.constants就能看见根模块空间的内容。  

好了,我们已经看见“绝对”和“相对”的区别。回到主题,为什么不能直接用ActionController::UnknownAction呢?这里涉及到Rails导入模块的一些“巫术”,使得当在Controller里用ActionController的时候指向的是
ActionWebService::Container::ActionController。所以要加个::让Ruby知道用的是根级的ActionController的。

可见这是个命名冲突的Rails bug, 框架应该对用户隐藏掉这种晦涩的东西。然而这个hack也不失为解决一般的命名冲突情况的办法。

分享到:
评论
6 楼 melin 2006-10-25  
相对路径和绝对路径的问题.
class test
  class String
    attr_accessor :temp
    def initialize(temp)
     @temp= temp
    end
  end
  def initialize(temp)
     @temp= String.new("e")
  end
end

@temp= String.new("e")这里的String理解为test::String
如果要引用ruby内建的String,就要
::String.new("e");
5 楼 cookoo 2006-10-24  
是啊rails的require方式太诡异了。难怪最近又出了个使用ActiveRecord但抛掉Rails别的部分的轻量级的ruby框架Merb,算上Camping现在一共有两个了。呼呼,看来Rails也快沦落成下一个J2EE了。

qiezi 写道
类似的问题在plugin里面也有。标准写法是写一个module,再调用某个要扩展或打补丁的类的class_eval方法,在里面include进去就行了,...
4 楼 Tin 2006-10-23  
奥,原来是这样呀,以后要多注意。
3 楼 qiezi 2006-10-23  
类似的问题在plugin里面也有。标准写法是写一个module,再调用某个要扩展或打补丁的类的class_eval方法,在里面include进去就行了,也可以直接写成:
class XXXModule::XXXClass
  # your code...
end

但如果写成:
module XXXModule
  class XXXClass
    # your code...
  end
end

就不会有效果,经过调试,发现后面这种写法实际上成了Rails::Initializer::XXXModule::XXXClass。
2 楼 riss 2006-10-23  
嗯,好东西,攒一个,谢谢!!!

这一点与C++好像差不多.这该是namespace的问题,和路径没什么关系吧!?
1 楼 robbin 2006-10-23  
我被这个问题困扰了一天,rails总是先到ActionWebService下面去找,所以总是找不到。

::ActionController::UnknownAction 有点

../action_controller/base.rb

的感觉,呵呵。

相关推荐

    08Ruby 模块.docx

    模块提供了一个命名空间,可以防止内部定义的方法或常量与外部环境中的同名元素发生冲突。例如,在`Trig`模块中定义的`sin`和`cos`函数不会与全局环境中的同名函数冲突。 **示例代码**: ```ruby module Trig PI = ...

    ruby基础教程(第四版)第8章 模块 1

    在Ruby编程语言中,模块(Module)是一个重要...总的来说,模块在Ruby中扮演着提供命名空间、实现功能复用和扩展类功能的角色。理解并熟练运用模块是掌握Ruby编程的关键,它可以帮助我们编写出更加清晰、可维护的代码。

    ruby(前途大好的ruby+rains)

    6. **模块(Module)**:Ruby的模块用于实现命名空间,代码重用和混合(mixin)功能。一个类可以包含多个模块,实现多重继承的效果。 7. **异常处理**:Ruby提供了异常处理机制,通过`begin..rescue..end`结构捕获...

    From Java to Ruby

    另外,Ruby中的模块(Module)和Java的包(Package)相似,但模块还扮演着命名空间和混入(Mix-in)的角色。混入允许模块中的方法被其他类直接继承和使用,这是一种不同于Java继承的独特方式。 在错误处理方面,...

    笨办法学ruby_笨办法学ruby_ruby_bravevk4_

    此外,你还会学习到Ruby的模块系统,它是组织代码和实现命名空间的一种方式。 Ruby的块(blocks)和 Proc 对象是其独特之处,它们提供了简洁的回调函数和迭代器。书中会深入解释这些概念,并通过实例展示它们在实际...

    ruby元编程.pdf

    5. 混入模块(Modules):模块是Ruby中实现命名空间、代码共享和混合功能的重要方式。通过混入模块,可以向类添加方法和行为,这是实现元编程的重要手段。 6. 动态方法和属性的创建:Ruby元编程允许程序在运行时...

    ruby ebook

    4. **模块**:Ruby的模块用于实现命名空间、混合-in(mixin)机制,帮助实现代码的复用和组织。 5. **元编程**:Ruby强大的元编程能力允许在运行时修改或创建代码,这是Ruby区别于其他语言的一大特色。 6. **标准...

    Ruby 语言基础(入门推荐)

    文档`ruby.doc`可能包含了Ruby的基本语法、数据类型、控制结构、类和对象的创建、模块和命名空间的使用、函数和方法的定义、异常处理、文件操作等内容。对于初学者来说,理解并掌握这些基础知识至关重要,因为它们...

    Ruby - Ruby for Rails

    - **命名空间管理**:讲解如何通过模块管理命名空间,避免命名冲突。 - **自包含代码块**:学习如何使用模块创建自包含的代码块,提高代码的清晰度。 #### 2.4 默认对象(self)与作用域 - **默认对象 self**:探讨 ...

    Ruby 基础语法 视频教程1

    - 不同类型的变量有各自的命名空间,不会互相冲突。 3. 表达式(Expressions): - **Ruby中的每一个语句都是一个表达式**,可以产生一个值。例如,`a = b + c`是一个表达式,它的结果是`b`和`c`的和。 - **算术...

    ruby-2.5.3-x64 下载

    4. 模块:用于实现代码重用和命名空间管理,类似于其他语言的命名空间或包。 5. 面向对象:所有一切都是对象,包括基本类型,提供了丰富的面向对象特性。 在Web开发中,Ruby on Rails(简称Rails)是一个基于Ruby的...

    模块的力量:Ruby中include与extend的深度解析

    在Ruby的世界里,模块是一种强大的工具,用于将方法和常量封装在一个命名空间内,从而实现代码的复用和组织。Ruby提供了两种方式来集成模块的功能:`include` 和 `extend`。 ##### `include` 关键字 `include` ...

    ruby经典

    10. **模块与命名空间**:模块用于组织代码,提供命名空间,防止命名冲突,并可通过`include`或`extend`引入模块的方法。 通过阅读"Ruby经典"这本书,读者将逐步了解并掌握以上知识点,从而在Ruby编程世界中...

    Ruby元编程pdf

    模块用于代码复用和命名空间管理,但也可作为混入(mix-in)来添加方法到类。 2. **方法**:Ruby的方法定义可以嵌套,并且可以动态添加或删除。`method_missing`是Ruby的一个特殊方法,当调用一个未定义的方法时,...

    Ruby v2.6.3 正式版

    5. **模块(Module)**:Ruby的模块用于封装相关的类和方法,实现代码复用和命名空间管理,防止命名冲突。 6. **元编程**:Ruby的元编程能力强大,允许在运行时修改类和对象的行为。例如,可以动态添加、删除或修改...

    ruby 经典教程从新手到专家

    - **程序结构**:探讨模块、混合和命名空间,如何组织大型Ruby项目。 #### 第二部分:进阶技巧 - **元编程**:讲解Ruby的元编程特性,如动态方法定义、符号和反射。 - **错误处理与调试**:教授如何有效处理错误和...

    Programming Ruby (English Version) and Source Code

    4. **模块(Module)**:Ruby的模块用于实现命名空间、混合(Mix-in)功能,以及提供类的方法集。 5. **方法和块的参数**:包括默认参数值、可变数量的参数、块参数等。 6. **异常处理**:Ruby中的`begin-rescue-...

    ruby.rar

    类定义了对象的行为,而模块则提供了命名空间和混合(mixin)功能,可以将行为插入到多个类中。 Ruby还拥有丰富的标准库,包括文件操作、网络通信、日期和时间处理等,这些都通过简单的API供开发者使用。此外,Ruby...

Global site tag (gtag.js) - Google Analytics