类,模块,闭包

10 Jul 2013, by

方法寻找

区别Ruby的require,load,和include

相同之处:三者均在kernel中定义的,均含有包含进某物之意。 不同之处: 1、requre,load用于文件,如.rb等等结尾的文件。 2、include则用于包含一个文件(.rb等结尾的文件)中的模块。 3、requre一般情况下用于加载库文件,而load则用于加载配置文件。 4、requre加载一次,load可加载多次。 (每当类包含一个模块时,该模块会被插入到祖先链中,位置在该类的正上方{include两个模块时,上面的更接近根类})

include与extend区别

在一个class中include一个模块的时候,模块方法将作为类实例方法,而extend模块的时候,模块方法会作为类方法。

不同情况选择类或者模块

对象和类

创建类方法

# 1
class Rubyist
  def self.who
    "Geek"
  end
end

# 2
class Rubyist
  class << self
    def who
      "Geek"
    end
  end
end

# 3
class Rubyist
end
def Rubyist.who
  "Geek"
end

#4
class Rubyist
end
Rubyist.instance_eval do
  def who
    "Geek"
  end
end
puts Rubyist.who # => Geek

# 5
class << Rubyist
  def who
    "Geek"
  end
end

私有(private)方法

public, private, protect 区别

事例代码:

# 实例对象不能访问private/protected方法

class Person
  def talk
    puts "public :talk,将调用speak"
    speak
  end

  protected
    def speak
      laugh
    end

  private
    def laugh
      puts "private:laugh"
    end
end
p1=Person.new
p1.talk

#p1.speak 实例对象不能访问protected方法
#p1.laugh 实例对象不能访问private方法

puts "-----------------------------------------------------"

# 子类可以访问private/protected方法

class Person
  protected
    def speak
      "protected:speak"
    end
  private
    def laugh
      "private:laugh"
    end
end

class Student < Person
  def useLaugh
    puts laugh
  end
  def useSpeak
    puts speak
  end
end

p2=Student.new
p2.useLaugh # => private:laugh
p2.useSpeak # => protected:speak

puts "----------------------------------------------------"

# protected方法可以在类和子类中指定给实例对象,private方法不可以

class Person
  protected
    def speak
      "protected:speak "
    end

  private
    def laugh
      "private:laugh"
    end

  def useLaugh(another)
    puts another.laugh #这里错误,私有方法不能指定对象
  end

  def useSpeak(another)
    puts another.speak
  end
end
p1=Person.new
p2=Person.new
p2.useSpeak(p1) # => protected:speak

#p2.useLaugh(p1)

闭包概念

def m(data, n)
  data.collect { |x| x*n }
end

puts m([1,2,3], 2)     #2,4,6
#collect迭代器关联的代码块使用了方法参数n
def m(n)
  lambda { |data| data.collect{|x| x*n} }
end
d = m(2)
puts d.call([1,2,3])     #2,4,6
#这个lambda在定义它的范围外被使用,称之为一个闭包,这个闭包封装了所绑定的方法参数n。

闭包和共享变量

def ac(i=nil)
  v = i
  g = lambda { v }
  s = lambda { |x| v = x }
  return g,s
end

gX,sX = ac(0)
puts gX[]   #0
sX[10]
pust gX[]   #10

闭包与绑定

闭包深入理解 跨越边界: 闭包