使用动态派发技术打破封装(Dynamic Dispatch)

它可以让我们在外部调用private方法

# Using dynamic dispatch, send method
# 使用动态派发技术打破封装,可以在外部调用private方法


class Student
  ENERGY_LOW = 50
  attr_accessor :name, :energy
  def initialize(name, energy=100)
    @name = name
    @energy = energy
  end

  def walk
    @energy -= 30
    puts "energy is #{@energy}"
  end

  def hungry?
    if @energy <= ENERGY_LOW
      puts "hungry!"
      puts "eating"
      eating
    else
      puts "full"
    end
  end

  private
    def eating
      puts "eating private"
      @energy += 20
    end
end


s1 = Student.new("lily")
puts s1.energy

s1.walk
s1.walk
s1.hungry?
puts s1.energy
s1.hungry?

# s1.eating
# dynamic_dispatch.rb:41:in `<main>': private method `eating' 
# called for #<Student:0x007fc02412b088 @name="lily", @energy=60> 
# (NoMethodError)


puts "==="
s1.send(:eating)
puts s1.energy