exams

周一为了准备周二的考试,作为review day,其实这个形式还是蛮不错的,之前完全不理解ActiveRecord返回的东西,怎么使用,现在这几天下来,基本知道怎么用了。看来这种有考试逼迫的填鸭式教学还是最有效率的。

周二上午讲了关于meta programming的一些内容,我觉得很有用,未来可能会在建立一些自己的类的时候用到。

Learning Objectives

  • Identify self in:
  • class definitions
  • class methods
  • instance methods
  • Describe the difference between class variables and class instance variables
  • Know how to use send and define_method (and method_missing if time allows) ********这个是重点。

Agenda

What is Metaprogramming?

  • The essence of programming is defining behavior
  • Metaprogramming is defining behavior that will define future behavior
  • A program is a set of instructions with some goal, ie a plan
  • ex: an exercise program, television programming, the 12 step program
  • Meta just means self-referential

Metaprogramming

Examples:

  • attr_reader/attr_writer
  • belongs_to/has_many
  • validates 这些function都是take in一系列的method名称,然后创建了getter和setter的,本身就是meta programming的典范。

Metaprogramming

Today we’ll explore just a small sample of those methods

require 'byebug'

class Pet
attr_reader :name

def initialize(name)
@name = name
end

def self.add_pet
@@total_pets ||= 0
@@total_pets += 1
end

def self.total_pets
@@total_pets
end

end

class Dog < Pet
puts self # Dog

def self.doggie_things
puts self # Dog
end

def who_am_i?
puts self # Dog instance
end

def self.record_dog_birth(dog)
@all_dogs ||= []
add_pet
@all_dogs << dog
end

def self.all
@all_dogs.each { |dog| puts dog.name }
end

def initialize(name)
super(name)
self.class.record_dog_birth(self)
@secret = "I'm a goat in disguise"
end

def do_this_then_that(this, that)
self.send(this) 这个就很有意思了,类似于javascript的call back function,可接收function 并执行。
self.send(that)
end

def do_this_with_args(this, *args)
self.send(this, *args)
end

def do_this_on_class(this)
Dog.send(this)
end

# def sleep
# puts "sleeping!"
# end

# def eat
# puts "eating!"
# end

# def drink
# puts "drinking!"
# end

# def self.create_tricks(*trick_names)
# puts self # Dog class
# trick_names.each do |trick_name|
# puts self # Dog class
# define_method(trick_name) do |num = 1|
# puts self # Dog instance
# num.times do
# puts "#{trick_name}ing!!!"
# end
# end
# end
# end

def method_missing(method_name, *args)
self.send(:define_method, method_name) do |*arguments|
arguments[0].times do
puts "#{method_name}ing!"
end
puts arguments[1]
end
self.send(method_name, *args)
end

def self.my_attr_reader(*method_names)
# Iterate over method names
# define methods with those names
# grab instance variables of that name
end

def trick
puts "BACK FLIP!!"
end

def juggle(thing, num)
num.times do
puts "juggling #{thing}!"
end
end

private

attr_reader :secret

def tell_secret
puts "My secret is: #{@secret}"
end
end

Designer transforming into a developer