ruby元编程读书笔记

1.ruby类
以下多次定义,并不是定义了多个ClassName类,是同一个类
当第一次使用class Shape定义这个类的时候,这个类并不存在,因此直接定义;当二次定义同样类名的类时,这个类已经存在,不再重新定义,而是打开这个类,在其中定义新方法。
irb(main):024:0> class Shape
irb(main):025:1> def print_width
irb(main):026:2> p @width
irb(main):027:2> end
irb(main):028:1> def initialize(width,length)
irb(main):029:2> @width = width
irb(main):030:2> @length = length
irb(main):031:2> end
irb(main):032:1> end
=> nil
irb(main):033:0> class Shape
irb(main):034:1> def print_length
irb(main):035:2> p @length
irb(main):036:2> end
irb(main):037:1> end
=> nil
irb(main):038:0> shape = Shape.new(1,2)
=> #<Shape:0x1b5a5cf @width=1, @length=2>
irb(main):039:0> shape.print_length
2
=> nil
irb(main):041:0> shape.print_width
1
=> nil
irb(main):042:0>


2.类方法定义的方式:
class User
  def self.p_basic_infor(name,age)
    p "#{name},#{age}"
  end

  def User.say_hello(name)
    p "#{name} say hello to you!"
  end

  class << self
    def update_infor(name)
      p "update the infor for #{name}"
    end
  end
end

User.p_basic_infor("tom",12)
User.say_hello("jack")
User.update_infor("Lily")
p User.singleton_methods

3.ruby实例变量
(1)只有给实例变量赋值的时候,实例变量才真正存在。
class User
  def method
    @v = 1
  end
end

user_1 = User.new
p user_1.instance_variables  #=〉[]

user_2 = User.new
user_2.method
p user_2.instance_variables  #=〉[@v]


(2)类变量是实例层面的,方法是类层面的,因此类的不同实例可以共用同一个方法,但是不同的实例却不能共用同一个实例变量。类的不同实例不能共用同一个实例变量见下面例子:
user_1 = User.new
user_1.method
p user_1.instance_variables  #["@v"]

user_2 = User.new
user_2.method
p user_1.instance_variables.equal?(user_2.instance_variables) #false



4.ruby作用域
ruby存在作用域的概念,出了某个作用域,变量的生命周期就结束了,常见的作用域门包括:class,def,module
冲破scope的方法是:
(1)使用Class.new代替class
(2)使用Module.new代替module
(3)使用define_method代替def
irb(main):001:0> name = "tom"
=> "tom"
irb(main):002:0> class User
irb(main):003:1> def p_name
irb(main):004:2> p "#{name} in the method"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> user = User.new
=> #<User:0x1bb326c>
irb(main):008:0> user.p_name
NameError: undefined local variable or method `name' for #<User:0x1bb326c>
        from (irb):4:in `p_name'
        from (irb):8

irb(main):001:0> length = 1
=> 1
irb(main):002:0> Shape = Class.new do
irb(main):003:1* define_method :p_length do
irb(main):004:2* p "#{length} is in the method"
irb(main):005:2> end
irb(main):006:1> end
=> Shape
irb(main):007:0> Shape.new.p_length
"1 is in the method"
=> nil
irb(main):008:0>


5.ruby块
ruby块不是对象,使用Proc可以将块转为对象,将块转为Proc的方法包括:
#method_1
inc = Proc.new   
inc.call(2)

#method_2
dec = lambda {|x| x-1}   
dec.call(2)

#method_3
def match(a,b)
  yield(a,b)
end
def do_match(a,b,&operation)
  p match(a,b,&operation)
end
do_match(3,2) {|x,y| x*y}

相反的,也可以将Proc转为block
#convert Proc to block
def my_method(a,b)
  p "#{yield(a,b)}"
end

my_proc = proc{|x,y| x+y}
my_method(1,2,&my_proc)


6.
(1)eigenclass是ruby的元类,是匿名类,在其中定义的方法称为Singleton Method
(2)打开eigenclass的方法有两种:
class User
  def print_inf
    p "user method"
  end

  class << self  #open eigenclass
    def say_hello  #define Singleton Method
      p "hello"
    end
  end
 
 def User.hello(name) #define Singleton Method
   p "hello, #{name}"
 end

  class << User  #open eigenclass
    def say_goodbye  #define Singleton Method
      p "goodbye"
    end
  end

  def self.say_hi
    p "hi"
  end
end

p User.singleton_methods

你可能感兴趣的:(Ruby)