Ruby10 Class Module Gem 深入

Agenda

  1. class_eval & instance_eval
  2. method_missing
  3. Module as a namespace
  4. Gems
  5. require vs load
  6. $LOAD_PATH

class_eval

  1. 首先class_eval是只有类才能调用的,Class#class_eval
  2. class_eval会重新打开当前类的作用域
# class_eval

class User
end


User.class_eval do

  attr_accessor :name
  def hello
    'hello'
  end
end

user = User.new
user.name = 'world'

puts user.name
puts user.hello

# module's self

module Management
  def self.track
    'track'
  end
end

class User
  include Management
end

# User.track # => error
Management.track

# class_eval in project

# requirement: we need to execute a class method when module included

module Manegement

  def self.included base #Manafement模块被其他类Included的时候会执行
    base.extend ClassMethods #User类注入ClassMethod

    base.class_eval do #打开User类
      setup_attribute
    end
  end

 # Manegement 内部模块 当引入Management的时候 会被引用为其他类的类方法
  module ClassMethods
    def setup_attribute
      puts 'setup_attribute'
    end
  end
end

class User
  include Manegement #目的是在include Management 的时候执行一些方法或者设置
end

instance_eval

  1. instance_eval 是所有类实例的方法
  2. 打开的是当前实例作用域
# instance_eval, instance methods and class methods
# 1. as a question

class User

end

User.class_eval do
  def hello
    'hello'
  end
end

User.instance_eval do
  def hi
    'hi'
  end
end

puts User.hi
user = User.new
puts user.hello
# puts user.hi #报错
# instance_eval, singleton_method

a = 'xxx'
a.instance_eval do
  def to_hello
    self.replace('hello')
  end
end


puts a.to_hello

# b = 'world'
# b.to_hello # => error
# class_eval as instance_eval

class User

end

User.class_eval do
  def hello
    'hello'
  end

  # works same as instance_eval
  def self.hi
    'hi'
  end

end

puts User.new.hello
puts User.hi

method_missing

  1. 当当前作用域上下文没有找到方法时就会调用
  2. method_missing方法
# metho missing
#
# 1. how it works
# 2. ancestors
# 3. rails's AR


class User

  def hello
    'hello from User'
  end

  def method_missing(name, *args)
    "method name is #{name} ,parameters :#{args}"
  end
end


user = User.new
puts user.hello

puts '-' * 30
puts user.hi('hello',19)

Namespace

  1. Module
  2. Class
  3. Constants

使用::来访问

# module as a namespace

module Management

  COMPANY_NAME = "Hello World Company"

  module Track
    def track
      'track from Track module'
    end
  end

  class User
    def hello
      'hello from User class'
    end
  end

end


puts Management::COMPANY_NAME

puts '-' * 30
include Management::Track
puts track

Gems

  1. Ruby的包管理工具,类似于linux的rpm,deb,python的pip,Node的npm,c#的nuget
  2. 社区中Gem包涵盖了各方面开发所需要的工具和组件
  3. 通过gem命令来安装

gem命令

  1. gem list
  2. gem install
  3. gem uninstall
  4. gem sources

关于墙内安装问题,可以使用ruby china的镜像地址

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/

bundle gem

  1. gem本身会有版本依赖问题
  2. bundle是一个gem,被用来管理其他gems
  3. bundle类似于linux的yum apt等等,是一个gems关系管理工具

bundle的基本使用

  1. gem install bundler
  2. Gemfile 文件
  3. bundle install/update/show/list

require vs load

相同点

  1. 都会在$LOAD_PATH下面查找当前要引入的文件

不同点

  1. require 调用文件时不需要.rb的文件后缀,而load需要
  2. require 针对童谣的文件只会调用一次,而load会反复调用
# require vs load

# 1. print require and load result

# require 'net/http'

puts require 'net/http' # => true
puts require 'net/http' # => false

# puts load 'net/http.rb'

puts Net::HTTP

$LOAD_PATH

  1. ruby代码的查找路径为当前的$LOAD_PATH环境变量
  2. ruby文件名命名规则: 文件的名字代表了当前 class/module的名字
# load_path

# require 'track'


$LOAD_PATH << File.expand_path('../track/lib',__FILE__)

require 'track'
require 'net/http'

puts Track::VERSION
puts Track::Parser.parse
posted @ 2018-02-20 22:24  罗道义  阅读(198)  评论(0编辑  收藏  举报
本站总访问量