Ruby元编程基础学习笔记整理


Posted in Python onJuly 02, 2016

笔记一:
代码中包含变量,类和方法,统称为语言构建(language construct)。

# test.rb
class Greeting
 def initialize(text)
  @text = text
 end

 def welcome
  @text
 end
end
my_obj = Greeting.new("hello")
puts my_obj.class
puts my_obj.class.instance_methods(false) #false means not inherited
puts my_obj.instance_variables

result =>
Greeting
welcome
@text

总结:
实例方法继承于类,实例变量存在于对象本身。
类和对象都是ruby中的第一类值。

应用示例:

mongo API for ruby => Mongo::MongoClient

# testmongo.rb
require 'mongo'
require 'pp'

include Mongo

# the members of replcation-set
# test mongodb server version 2.6.0
host = "192.168.11.51"
# The port of members
# If the port is 27017 by default then otherport don't need to assignment
otherport = ""
port = otherport.length != 0 ? otherport : MongoClient::DEFAULT_PORT

opts = {:pool_size => 5, :pool_timeout => 10}
# Create a new connection
client = MongoClient.new(host, port, opts)

# puts client.class
puts client.class.constants
puts client.instance_variables
puts client.class.instance_methods(false)

分别输出

Constant, Instance Attribute, Instance Method

笔记二:动态调用
当你调用一个方法时,实际是给一个对象发送了一条消息。

class MyClass
 def my_method(args)
  args * 10
 end
end
obj = MyClass.new

puts obj.my_method(5)
puts "**"
puts obj.send(:my_method, 6)

结果:

50
**
60

可以使用object#send()取代点标记符来调用MyClass#my_method()方法:

obj.send(:my_method, 6)

send()方法第一个参数是要发送给对象的消息,可以是符号(:symbol)或字符串,其他参数会直接传递给调用的方法。
可以动态的决定调用哪个方法的技术,成为Dynamic Dispatch。

笔记三:符号和字符串的区别
1. 符号不可变,可以修改字符串中的字符。
2. 针对符号的操作更快些。
3. 通常符号用来表示事物的名字。
例如:

puts 1.send(:+, 4) => 5
String#to_sym(),String#intern() => string to symbol
String#to_s(),String#id2name() => symbol to string
"caoqing".to_sym() => :caoqing
:caoqing.to_s() => "caoqing"

动态派发中使用模式派发(pattern dispatch)的方法。

puts obj.class.instance_methods(true).delete_if{ |method_name| method_name !~ /^my/}
result => 
my_method

笔记四:动态定义
使用Module#define_method()方法定义一个方法。

class MyClass
 define_method :my_method do |args|
  args * 3
 end
end
obj = MyClass.new
puts obj.my_method(10)

结果:30

单件方法允许给单个对象增加一个方法。singleton methods

# test.rb
str = "My name is caoqing."
def str.title?
 self.upcase == self
end

puts str.title?
puts str.methods.grep(/^title?/)
puts str.singleton_methods

结果:

false
title?
title?

笔记五:
类方法的本质,类是对象,类名是常量。在类上调用方法和对象调用方法一样:

obj.my_method
Cla.class_method

Duck Typing:对象能不能响应方法,可以是普通方法或者单件方法。
类方法的实质就是他们是类的一个单件方法。

def obj.method
 # method body
end

obj可以是对象引用,常量类名或self。

类宏(Class Macro)
Ruby对象没有属性,可以使用拟态方法定义属性。
Module#attr_*()方法中的一员来定义访问器。类宏不是关键字而是方法。

Eigenclass
单件方法按照常规的方法查找在祖先链无法找到保存的地方,obj是对象不能保存,也不能存在于class内,否则所有的实例都可以共享这个方法。
对象拥有一个特有的隐藏类,称为该对象的eigenclass。
进入eigenclass作用域:

class << obj
 code
end

如果想获取eigenclass的引用,则可以在离开该作用域时返回self:

附录:
类变量,实例变量,类方法,实例方法区别
@@                            :var类变量
@                            :实例变量
self(?clas,::).method        :类方法
method                        :实例方法

# test.rb
class Foo
 @@var = "lion"
 def self.method01
  puts "cat"
  @name = "cat"
  @@var = "cat"
  puts @name
 end

 def self.method02
  puts "tiger"
  @name = "tiger"
  @@var = "tiger"
  puts @name
 end

 def self.method03
  puts "dog"
  @name = "dog"
  @@var = "dog"
  puts @name
 end

 def putsname
  puts @name
  puts @@var
 end
end

obj = Foo.new
# obj.method01   => (NoMethodError)

obj.putsname   => lion

Foo.method01
Foo.method02
Foo.method03
obj.putsname

结果:

lion
cat
cat
tiger
tiger
dog
dog

dog
Python 相关文章推荐
Python列表list数组array用法实例解析
Oct 28 Python
python链接Oracle数据库的方法
Jun 28 Python
python开发之str.format()用法实例分析
Feb 22 Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
Feb 08 Python
numpy.delete删除一列或多列的方法
Apr 03 Python
mac下如何将python2.7改为python3
Jul 13 Python
django 使用全局搜索功能的实例详解
Jul 18 Python
Django实现后台上传并显示图片功能
May 29 Python
python判断一个变量是否已经设置的方法
Aug 13 Python
python在地图上画比例的实例详解
Nov 13 Python
Python中文分词库jieba(结巴分词)详细使用介绍
Apr 07 Python
python中 .npy文件的读写操作实例
Apr 14 Python
Python的爬虫程序编写框架Scrapy入门学习教程
Jul 02 #Python
搭建Python的Django框架环境并建立和运行第一个App的教程
Jul 02 #Python
Python使用poplib模块和smtplib模块收发电子邮件的教程
Jul 02 #Python
python图片验证码生成代码
Jul 02 #Python
Python彩色化Linux的命令行终端界面的代码实例分享
Jul 02 #Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
Jul 02 #Python
Python使用ntplib库同步校准当地时间的方法
Jul 02 #Python
You might like
php实现refresh刷新页面批量导入数据的方法
2014/12/23 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
[原创]php使用curl判断网页404(不存在)的方法
2016/06/23 PHP
php版微信公众平台实现预约提交后发送email的方法
2016/09/26 PHP
Yii2 hasOne(), hasMany() 实现三表关联的方法(两种)
2017/02/15 PHP
浅谈php调用python文件
2019/03/29 PHP
Extjs学习笔记之九 数据模型(上)
2010/01/11 Javascript
基于jquery创建的一个图片、视频缓冲的效果样式插件
2012/08/28 Javascript
浅谈jquery的map()和each()方法
2016/06/12 Javascript
JS仿百度自动下拉框模糊匹配提示
2016/07/25 Javascript
javascript 动态脚本添加的简单方法
2016/10/11 Javascript
Bootstrap基本组件学习笔记之缩略图(13)
2016/12/08 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
js 将canvas生成图片保存,或直接保存一张图片的实现方法
2018/01/02 Javascript
Puppeteer环境搭建的详细步骤
2018/09/21 Javascript
javascript创建元素和删除元素实例小结
2019/06/19 Javascript
js 闭包深入理解与实例分析
2020/03/19 Javascript
详解ES6中class的实现原理
2020/10/03 Javascript
[02:47]3.19DOTA2发布会 国服成长历程回顾
2014/03/25 DOTA
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
Python3.x版本中新的字符串格式化方法
2015/04/24 Python
Django返回json数据用法示例
2016/09/18 Python
Python发送http请求解析返回json的实例
2018/03/26 Python
python并发和异步编程实例
2018/11/15 Python
Python编程flask使用页面模版的方法
2018/12/28 Python
详解Python正则表达式re模块
2019/03/19 Python
详解Numpy数组转置的三种方法T、transpose、swapaxes
2019/05/27 Python
Python 使用type来定义类的实现
2019/11/19 Python
python 字典访问的三种方法小结
2019/12/05 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
Python实现简单的2048小游戏
2021/03/01 Python
CSS3色彩模式有哪些?CSS3 HSL色彩模式的定义
2016/04/26 HTML / CSS
2014年酒店工作总结与计划
2014/11/17 职场文书
档案接收函格式
2015/01/30 职场文书
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
Python OpenCV超详细讲解基本功能
2022/04/02 Python