##Open Class## 给予了你为class增加方法的能力,但是也如同打开了潘多拉魔盒,一旦通过Open Class增加了class方法导致重名问题,将很难定位。

##Instance variable## 和Java不同,Ruby中的instance_variable 与class之间没有直接联系,你可以从一个class创建不同实例,并且各自拥有不同的instance variable. (What’s the purpose?)

##Method## Ruby中,method保存在class中

##Object## 一个object是一组instance variable以及这个object所属的class的引用.

##Class## Ruby中,所有的class都是类Class的instance object. class是一个Class的实例、一组instance method、一个到super class的引用.

##Differences between Class and Module## Module is meant to be included (or mixined). Module can be used as namespace. Class is meant to be initlized or inherinted.

##Dynamic Methods## ruby中,可以在class定义时通过define_methods动态地定义方法, 如下代码动态地为class Computer添加了三个方法 mouse, cpu, keyboard:

class Computer
	def initialize(computer_id, data_source)
	  @id = computer_id
	  @data_source = data_source
	end

  def self.define_component(name) 
	define_method(name) {
  		info = @data_source.send "get_#{name}_info", @id
	    price = @data_source.send "get_#{name}_price", @id 
      "#{name.to_s.capitalize}: #{info} ($#{price})" 
	}
  end

  define_component :mouse
  define_component :cpu
  define_component :keyboard
end

##Method Missing## ruby中,当尝试对receiver调用一个不存在的方法时,该receiver的method_missing方法会被调用,利用这一特性,可以通过重载 method_missing实现动态定义属性、方法效果, 通过method missing机制定义出来的方法被称为Ghost Method。 例如:

class Computer
  def initialize(computer_id, data_source)
    @id = computer_id
    @data_source = data_source
  end

  def method_missing(name, *args)
    info = @data_source.send("get_#{name}_info", args[0])
    price = @data_source.send("get_#{name}_price", args[0])
    "#{name.to_s.capitalize}: #{info} ($#{price})"
  end
  
  #重写respond_to会使利用method_missing实现的动态方法与实际定义的方法无异
  def respond_to?(method)
    @data_source.respond_to?("get_#{method}_info") || super
  end
end

这些通过method_missing机制创建出来的methods被称为ghost method.

##Flat Scope## 在ruby中,classmodule,def被称为scope gate,当程序遇到这几个关键字时,程序的scope就会发生变化,如果需要在scope之间共享变量,则可以使用Class.new代替classmodule, Module#define_method代替def,如:

my_var = 12
MyClass = Class.new do
  # my_var is visiable here
  ...
  define_method :my_method do
    # my_var is visiable here
  end
end

##Object#instance_eval()## 改变self的值为指定实例,同时改变“current class”为当前实例的eigenclass, 在此实例上下文中执行一个block

##Module#class_eval() or Module#module_eval()## 改变self的值为指定实例,同时改变“current class”为当前方法的receiver,在此实例上下文中执行一个block

##Deferred Evaluation## 定义一个block,proc,lambda,然后在其他地方调用此block,proc,lambda,这就叫做Deferred Evaluation

##Singleton Method## 单独给一个object instance定义的method,称之为singleton method

class methods可以认为是一个class对象的singleton method

##Class Macro## class macro看起来像是关键字,但是实际上就是普通的方法,但是这些方法常在声明定义class中使用。

##Eignclass## 对象除了有一个其被创建时声明的那个class外,还会有它自己的一个不可见的,特殊的class,这个class被叫做eigenclass,也被称为singleton class。一个对象的singleton method就存在于这个对象的eignclass上,eignclass的superclass是这个对象的对外呈现的那个class(参考下面的示例代码)。

class Duck
	#code omited
end
#Duck就是a_duck对外呈现的class
a_duck = Duck.new

通过下面的语法,你可以进入到一个对象的eignclass内部

class << obj
  # you are in the eigen class scope.
end

或者可以通过下面的语法获取对eignclass的引用

metaclass = class << matz; self; end

###Scope changing class Person #self is the class object Person class « self #self is the eignclass of class object Person def species “Homo Sapien” end end end

Person.instance_eval do
  #method will be defined on eignclass	of class object `Person`
  #but self is the class object `Person`
  def species
	"Homo Sapien"
  end
   
  self.name #=> "Person"
end

###给对象的eignclass增加singleton方法:

#给对象增加singleton方法
matz = Object.new
def matz.speak
  "Place your burden to machine's shoulders"
end

#给类增加singleton方法(class methods)
class Person
end

def Person.speak 
  "Place your burden to machine's shoulders"
end

##Class Extension Mixin

module M
  def included(clazz)
	clazz.extend ClassMethods
  end

  #定义在这个内部module里的方法会变成inclusor的class method
  module ClassMethods
	def a_class_method
    end
  end
end

readable angular tests

In this post, I'll provdes some tips to create readable angular test.### General Tips#### Use describe or nested describe to structure sp...… Continue reading

Exposing event stream from monolith

Published on September 18, 2017