Ruby类,包含和作用域 [英] Ruby classes, include, and scope

查看:92
本文介绍了Ruby类,包含和作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

包括模块如何影响范围?具体来说,在此示例中:

How does including a module affect scope? Specifically, in this example:

module ModuleA
  class ClassA
    def initialize
      puts "test passed"
    end
  end
end

module ModuleB
  include ModuleA

  # test 1
  C = ClassA.new

  class ClassB
    def initialize
      c = ClassA.new
    end
  end
end

# test 2 and 3 fail without this
#include ModuleB

module ModuleC
  # this doesn't help
  include ModuleB

  # test 2
  ClassB.new

  # test 3
  ModuleB::ClassB.new
end

测试1 可以正常工作,但是测试2 测试3 在没有注释掉的import ModuleB的情况下会失败.

test 1 works fine, but test 2 and test 3 fail without the commented-out import ModuleB.

  • 为什么ClassA在范围内的ModuleB(测试1)内,但不在ClassB内?
  • 为什么import ModuleBClassA带入ClassB中的范围?
  • Why is ClassA in scope inside of ModuleB (test 1) but not in ClassB?
  • Why does the import ModuleB bring ClassA into scope in ClassB?

推荐答案

关键字 class module def 范围门".他们创建了新的范围.

The keywords class, module and def are what is known as "scope gates". They create new scopes.

#!/usr/bin/env ruby

module ModuleA
  class ClassA
    def initialize
      puts "test passed"
    end
  end
end

module ModuleB
  include ModuleA

  # test 1
  c = ClassA.new  # this works as ModuleA has been included into this module

  class ClassB  # class is a scope gate, creates new scope
    def initialize  # def is a scope gate, creates new scope
      c = ModuleA::ClassA.new  # must fully qualify ClassA
    end
  end

  ClassB2 = Class.new do  # no scope gate
    define_method :initialize do # no scope gate
      c = ClassA.new  # this works, no need to fully qualify
    end
  end
end

b = ModuleB::ClassB.new
b2 = ModuleB::ClassB2.new

在阅读书之后,我开始了解Ruby中的作用域元编程Ruby" .确实很启发人.

I began to understand scopes in Ruby after reading the book "Metaprogramming Ruby". It is truly enlightening.

编辑:针对下面的评论.

类本质上是Ruby常量(请注意,它是一个具有大写名称的对象).常量在范围内具有定义的查找算法. Ruby编程语言 O'Reilly的书很好地解释了这一点在第7.9节中.此博客文章.

A class is essentially a Ruby constant (notice that it is an object with a capitalized name). Constants have a defined lookup algorithm within scopes. The Ruby Programming Language O'Reilly book explains it well in section 7.9. It is also briefly described in this blog post.

在任何类或模块之外定义的顶级常量类似于顶级方法:它们在Object中隐式定义.当从类中引用顶级常量时,将在搜索继承层次结构时对其进行解析.如果在模块定义中引用了常量,则在搜索模块的祖先后将对Object进行显式检查.

Top-level constants, defined outside of any class or module, are like top-level methods: they are implicitly defined in Object. When a top-level constant is referenced from within a class it is resolved during the search of the inheritance hierarchy. If the constant is referenced within a module definition it does an explicit check of Object after searching the ancestors of the module.

这就是为什么在顶层包含ModuleB会使ModuleB中的类在所有模块,类和方法中可见的原因.

That's why include ModuleB at the top level makes the class in ModuleB visible in all modules, classes and methods.

这篇关于Ruby类,包含和作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆