Hooks in Ruby

Ruby中钩子,钩子们,来吧

https://www.sitepoint.com/rubys-important-hook-methods/

# included
module Person
  
  def name
    puts "My name is Person"
  end

  module ClassMethods
    def class_method_1
      puts "Class method is called"
    end
  end

  module InstanceMethods
    def instance_method_1
      puts "instance method is called"
    end
  end

  def self.included(receiver)
    receiver.extend         ClassMethods
    receiver.send :include, InstanceMethods
    puts "#{receiver} included #{self}"
  end
end


class User
  include Person
end

user = User.new
user.name
user.instance_method_1
user.class.class_method_1
p User.ancestors

puts "="*16
# extended
module Animal
  def name
    puts "I'm an animal"
  end

  def self.extended(receiver)
    puts "#{receiver} extended #{self}"
  end
end

class Dog
  extend Animal
end

Dog.name

puts "="*16
# prepended
module Ship
  def name
    puts "I'm a ship"
  end

  module ClassMethods
    def class_method_1
      puts "Class method is called"
    end
  end

  module InstanceMethods
    def instance_method_1
      puts "instance method is called"
    end
  end

  def self.prepended(receiver)
    receiver.extend         ClassMethods
    receiver.send :prepend, InstanceMethods
    puts "#{receiver} prepended #{self}"
  end

end

class Boat
  prepend Ship

  def name
    puts "I'm a boat. I should be overried by Ship so you won't see me."
  end
end

Boat.new.name
Boat.new.instance_method_1
p Boat.ancestors
Boat.class_method_1

puts "="*16
# inherited
class Parent

  def self.inherited(child_class)
    puts "#{child_class} inherits #{self}"
  end

  def name
     "My name is Parent"
  end
end

class Child < Parent
end

puts Child.new.name # => My name is Parent
p Child.ancestors

puts "="*16
# method_missing
class Coffee
  def price
    2
  end

  def name
    "I'm a coffee"
  end
end

class Milk
  def initialize(coffee)
    @coffee = coffee
  end
  
  def price
    super + 0.2
  end
  
  def method_missing(meth, *args)
    "#{meth} not defined on #{self}"
    if @coffee.respond_to?(meth)
      @coffee.send(meth, *args)
    else
      super
    end
  end

end

coffee = Coffee.new
coffee_with_milk = Milk.new(coffee)
p coffee_with_milk.price
p coffee_with_milk.name
p coffee_with_milk.class.instance_methods(false) #you won't see #name method

总结Ruby中的Scope:

  • def…end, class…end, module…end都是作用域门,进入他们就会出现新的scope
  • block是特殊的scope,block中initialize的局部变量在外部没法访问
  • 扁平作用域可以用,define_method, Class.new, Module.new来实现。

转载需保留链接来源:软件玩家 » Hooks in Ruby

赞 (0)

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

感谢您的支持!

微信扫一扫打赏