视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Ruby元编程基础学习笔记整理
2020-11-27 14:29:00 责编:小采
文档


笔记一:
代码中包含变量,类和方法,统称为语言构建(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

下载本文
显示全文
专题