Ruby for Rails 最佳实践Ⅶ

来源:互联网 发布:如何使用万德数据库 编辑:程序博客网 时间:2024/06/03 19:24

第七章 默认对象(self)和作用域

一、理解当前对象或默认对象 self

1. 在不同上下文中判定 self

puts "Tol Level"

puts "self is #{self}" #输出 main

 

class C

         puts "Class definition block:"

         puts "self is #{self}" #输出 C

        

         def self.x

                   puts "Class method C.x:"

                   puts "self is #{self}"#输出 C

         end

        

         def m

                   puts "Instance method C#x:"

                   puts "self is #{self}"#输出 #<C:0x2c029b4>

         end

end

 

2. 在类和模块定义中的 self

class C

         puts "Just started class C:"

         puts self #输出 C

        

         module M

                   puts "Nested module C::M:"

                   puts self#输出 C::M

         end

        

         puts "Back in the outer level of C:"

         puts self #输出 C

end

 

3. 单例方法定义和类方法定义中的 self

(1)在执行单例方法时,self 是拥有该方法的对象

obj = Object.new

 

def obj.show_me

         print "I'm an object; "

         puts "here's self inside a singleton method of mine:"

         puts self

end

 

obj.show_me

print "And inspecting obj from outside, "

puts "to be sure it's the same object:"

p obj

 

输出结果

I'm an object; here's self inside a singleton method of mine:

#<Object:0x2c02dec>

And inspecting obj from outside, to be sure it's the same object:

#<Object:0x2c02dec>

 

(2)类方法中的 self 就是类本身,因此

class C

         def C.x

                   puts "Class method of class C"

                   puts self

         end

end

 

等同于

class C

         def self.x

                   puts "Class method of class C"

                   puts self

         end

end

 

二、确定作用域

1. 全局变量具有全局作用域,全局变量通过变量名前加美元符号($)来识别

$gvar = "I'm a global!"

class C

         def examine_global

                   puts$gvar

         end

end

C.new.examine_global

 

2. Ruby 内建全局变量

(1)$0 包含了 Ruby 正在执行的文件的名字

(2)$: 包含了一些目录,在加载一个外部文件时,这些目录构成了 Ruby 搜索路径

(3)$$ 包含了 Ruby 进程的进程ID

 

3. 全局变量使用范例

class Work

   def show_info

     puts "Title and composer: #{$title}, #{$composer}"

   end

 end

 

 work = Work.new

 $composer = "Giuseppe Verdi"

 $title = "La Traviata"

 work.show_info

 

3. 局部作用域

class C

   a = 5

   module M

     a = 4

     module N

       a = 3

       class D

         a = 2

         def show_a

           a = 1

           puts a

         end

         puts a #输出 2

       end

       puts a #输出 3

     end

     puts a #输出 4

   end

   puts a #输出 5

 end

 

 d = C::M::N::D.new

 d.show_a #输出 1

 

4. 常量的作用域和解析

module M

         class C

                   X = 2

                   class D

                            module N

                                     X = 1

                            end

                   end

         end

end

puts M::C::D::N::X #输出 1

puts M::C::X #输出 2

 

5. 强制使用绝对常量路径(::)

class Violin

         # Violin 中再创建一个 String 类

         class String

                   attr_accessor :pitch

                   def initialize(pitch)

                            @pitch = pitch

                   end

         end

        

         # 如果想调用 Ruby 自带的 String 类,则使用 ::String.new(args)

         def history

                  ::String.new(maker + ", " + Date)

         end

end

 

三、部署访问权限规则

1. 私有方法:Ruby 通过禁止对私有方法使用显式的接收者来获得私有特性,在所有可以省略接收者的场合,调用私有方法是没问题的

class C

         private

         def sayHello

                   puts "hello"

         end

         #或者使用 private :sayHello

end

 

2. 保护方法:只要默认对象(self)和你想调用的方法所属的对象是同一类的实例,你就可以调用该保护方法

class C

  def initialize(n)

    @n = n

  end

 

  def n

    @n

  end

 

  def compare(c)

    if c.n > n

      puts "The other object's n is bigger."

    else

      puts "The other object's n is the same or smaller."

    end

  end

 

  protected :n

end

 

c1 = C.new(100)

c2 = C.new(101)

c1.compare(c2)

 

3. 公有方法:默认的访问级别

 

四、编写和使用顶层方法

1. 预定义的(内建的)顶层方法:如 puts 和 print 都是 Kernel 内建的私有实例方法。

2. 查看所有内建私有实例方法:puts Kernel.private_instance_methods.sort


原创粉丝点击