debbbbie Writings

深藏功与名

Follow me onGitHub

《Metaprogramming Ruby》学习笔记二 之 Class Definitions

《Metaprogramming Ruby》学习笔记二 之 Class Definitions

The Current Class

In a class definition,the current object self is the class being defined, the current class is the same as self

All methods defined with def become instance methods of the current class.

If you have a reference to the class, you can open the class with class_eval() or module_eval()

The Current Class and Special Cases

ths current class is MyClass

class_eval()

def add_method_to(a_class)
  a_class.class_eval do 
    def m
      'Hello!'
    end
  end
end

Class Instance Variables

class MyClass
  @my_var = 1
  def self.read
    @my_var
  end

  def write
    @my_var = 2
  end

  def read
    @my_var
  end
end

obj = MyClass.new
obj.write
obj.read     # => 2

MyClass.read # => 1

Class Variables

different from Class Instance Variables, they can be accessed by subclasses and by regular instance methods.

a nasty habit that make it be shuned by Class Instance Variables

@@v = 1
class MyClass
  @@v = 2
end

@@v # => 2

Duck Typing

Singleton Methods

Class Macros

Methods that are defined on class Module, you can use them whenever self is a module or a class.

Class Macros look like keywords, but they're just regular class methods that are meant to be used in a class definition

deprecate

class MyClass
  def self.deprecate(old_method, new_method)
    define_method(old_method) do |*args, &block|
      warn "Warning: #{old_method}() is deprecated. Use #{new_method}() instead."
      send(new_method, *args, &block)
    end
  end
  deprecate :get_title, :title
  deprecate :title2, :subtitle
end

Eigenclasses

object.instance_method

examples

eigenclass = class << Object.new
  self
end
eigenclass.class # => Class
class Object
  def eigenclass
    class << self; self; end
  end
end
"abc".eigenclass # => #<Class:#<String:0x331df0>>

Method Lookup and eigenclasses

eigenclass

Eigenclasses and Inheritance

eigenclass

Class Attributes

class MyClass
  class << self
    attr_accessor :c
  end
end
MyClass.c = "It works!"
MyClass.c #=> "It works!"

Class attributes live in the class's eigenclass

eigenclass

Module Trouble

module MyModule; def my_method;end; end
class MyClass
  class << self
    include MyModule
  end
end
MyClass.my_method

Object#extend

a shortcut that includes a module in the receiver's eigenclass

module MyModule
  def my_method
    'Hello'
  end
end

class MyClass
  extend MyModule
end
MyClass.my_method # => 'Hello'

Method Aliases

  alias :new_method, :old_method

Around Aliases

When you redefind a method, you don't really change the method.Instead, you define a new method add attach an existing name to that new method.

write an Around Alias in three simple steps alias a method; rededine it; call the old method from the new method

class String
  alias :real_length :length
  def length; real_length>5 ? 'long':'short' end
end
"debbie".length #=>long

"debbie".real_length #=> 13
module Kernel
  alias gem_original_require require
  def require path
    gem_original_require path
  rescue LoadError => load_error
    if load_error.message =~ /#{Regexp.escape path}\z/ and spec = Gem.searcher.find(path)
      Gem.activate(spec.name, "= #{spec.version}")
      gem_original_require path
    end
  end
end