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

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

相关推荐

  • Ruby元编程小结

    今天被问到此类问题,以前总是觉得这个是比较宽泛的一个概念,自己即使是用过这些特性,但却一直不知道这叫"元编程" 直到今天被人问起的时候,方才顿悟一些,随后便在网上和自己的平实用的一些元编程做个小总结. 原来所谓的Ruby中的元编程,是可以在运行时动态的操作语言结构(如类.模块.实例变量等)的技术.你甚至于可以在不用重启的情况下,在运行时直接键入一段新的Ruby代码,并执行他. Ruby的元编程,也具有"利用代码来编写代码"的作用.例如,常见的attr_accesso

  • ruby元编程实际使用实例

    很喜欢ruby元编程,puppet和chef用到了很多ruby的语言特性,来定义一个新的部署语言. 分享几个在实际项目中用到的场景,能力有限,如果有更优方案,请留言给我:) rpc接口模板化--使用eval.alias.defind_method require 'rack/rpc' class Server < Rack::RPC::Server def hello_world "Hello, world!" end rpc 'hello_world' => :hello

  • Ruby元编程之梦中情人method_missing方法详解

    我最近读了些文章(比如这篇),宣传在 Ruby 里使用 method_missing 的. 很多人都与 method_missing 干柴烈火,但在并没有小心处理彼此之间的关系.所以,我想来探讨一下这个问题: ** 我该怎么用 method_missing ** 什么时候该抵挡 method_missing 的诱惑 首先,永远不要在还没花时间考虑你用得够不够好之前,就向 method_missing 的魅力屈服.你知道,在日常生活中,很少会让你以为的那样亟需 method_missing: 日常

  • Ruby元编程技术详解(Ruby Metaprogramming techniques)

    我最近考虑了很多元编程(Metaprogramming)的问题,并希望看到更多这方面技术的例子和讲解.无论好坏,元编程已经进入Ruby社区,并成为完成各种任务和简化代码的标准方式.既然找不到这类资源,我准备抛砖引玉写一些通用Ruby技术的文章.这些内容可能对从其它语言转向Ruby或者还没有体验到Ruby元编程乐趣的程序员非常有用. 1. 使用单例类 Use the singleton-class 许多操作单个对象的方法是基于操作其单例类(singleton class),并且这样可以使元编程更简

  • Ruby和元编程之万物皆为对象

    开篇 空即是色,色即是空. 空空色色,色色空空,在Ruby语言中,万物皆为对象. Ruby是一个面向对象的语言(Object Oriented Language),面向对象的概念比其他语言要贯彻的坚定很多. Ruby中不存在Java中原始类型数据和对象类型数据之分.大部分Ruby中的的东东都是对象. 所以,想要掌握Ruby和Ruby的元编程,对象就是第一门必修功课.本回就着重研究一下Ruby中的对象. Ruby中的对象 如果你从其他面向对象的语言转来,一提到得到一个对象你可能会想到建立一个类,然

  • Ruby元编程的一些值得注意的地方

    避免无限循环的元编程. 写一个函数库时不要使核心类混乱(不要使用 monkey patch). 代码块形式最好用于字符串插值形式.         当你使用字符串插值形式,总是提供 __FILE__ 和 __LINE__,使得你的回溯有意义. class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__ define_method 最好用 class_eval{ def ... } 当使用 class_eva

  • ruby元编程之创建自己的动态方法

    method_missing是Ruby元编程(metaprogramming)常用的手法.基本思想是通过实现调用不存在的方法,以便进行回调.典型的例子是:ActiveRecord的动态查找(dynamic finder).例如:我们有email属性那么就可以调用User.find_by_email('joe@example.com'),虽然, ActiveRecord::Base并没有一个叫做find_by_email的方法. respond_to? 并不如method_missing出名,常用

  • ruby元编程之method_missing的一个使用细节

    我们知道顶级域,定义域的self是啥? 复制代码 代码如下: puts self    #main puts self.class #Object 我们知道当一个方法被调用的时候,如果没有对象接受,默认就是self,如: 复制代码 代码如下: def tell_me_who     puts self end tell_me_who  #main 方法调用是这样的步骤,先查找当前对象的所在类的实例方法存在方法与否,如果存在,调用方法,如果不存在则查看superclass,直到 BasicObje

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

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

  • C#学习笔记整理_变量等基础语法(必看篇)

    C#学习笔记1: 变量的作用域冲突时,调用实例变量:this.a,调用类变量:类名.a 常量总是静态的,必须初始化,一般用全大写格式,声明关键字为const,如const int NUNBE = 10; C#的基本预定义类型内置于.NET Framework结构中(System),object是基类: 整型:System.SByte.System.Int16.System.Int32.System.Int64 有符号的8位.16位.32位.64位分别表示为sbyte.short.int.long

  • Python学习笔记整理3之输入输出、python eval函数

    1. python中的变量: python中的变量声明不需要像C++.Java那样指定变量数据类型(int.float等),因为python会自动地根据赋给变量的值确定其类型.如 radius = 20,area = radius * radius * 3.14159 ,python会自动的将radius看成"整型",area看成"浮点型".所以编程时不用再像之前那样小心翼翼的查看数据类型有没有出错,挺人性化的. 2. input和print: 先贴个小的程序 #

  • Java中jqGrid 学习笔记整理——进阶篇(二)

    相关阅读: Java中jqGrid 学习笔记整理--进阶篇(一) 本篇开始正式与后台(java语言)进行数据交互,使用的平台为 JDK:java 1.8.0_71 myEclisp 2015 Stable 2.0 Apache Tomcat-8.0.30 Mysql 5.7 Navicat for mysql 11.2.5(mysql数据库管理工具) 一.数据库部分 1.创建数据库 使用Navicat for mysql创建数据库(使用其他工具或直接使用命令行暂不介绍) 2. 2.创建表 双击打

  • jqGrid 学习笔记整理——进阶篇(一 )

    在浏览导航栏添加所需按钮 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>DEMO</title> <link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css" /> <link rel=&

  • 值得收藏的asp.net基础学习笔记

    值得收藏的asp.net基础学习笔记,分享给大家. 1.概论 浏览器-服务器 B/S 浏览的 浏览器和服务器之间的交互,形成上网B/S模式 对于HTML传到服务器  交给服务器软件(IIS)  服务器软件直接读取静态页面代码,然后返回浏览器 对于ASPX传达服务器  交给服务器软件(IIS)   IIS发现自己处理不了aspx的文件,就去映射表根据后缀名里找到响应的处理程序(isapi,服务器扩展程序) 问题:IIS如何调用可扩展程序? 答:可扩展程序首先就是按照IIS提供的借口实现代码,所以I

  • Javascript基础学习笔记(菜鸟必看篇)

    什么是变量? 变量是用于存储信息的容器 变量的声明 语法: var 变量名 变量名 = 值; 变量要先声明再赋值 变量可以重复赋值 变量的命名规则 变量必须以字母开头: 变量也能以$和_符号开头(不过我们不推荐这么做): 变量名称对大小写敏感(a和A是不同的变量). 语句 语句以一个分号结尾:如果省略分号,则由解析器确定语句的结尾. 有个好的编码习惯,都要以 ; 结尾 数据类型 在JavaScript中,一段信息就是一个值(value).值有不同的类型,大家最熟悉的类型是数字.字符串(strin

  • JavaScript学习笔记整理_setTimeout的应用

    setTimeou的t应用 var ids = []; function foo1(i) { this.i = i; console.log('i = '+i); ids[0] = setTimeout((function () { foo1(i); }),1000); } function foo2(j) { this.j = j; console.log('j = '+j); ids[1] = setTimeout((function () { foo2(j); }),1000); } fo

随机推荐