- 浏览: 1399886 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
1 理解allocate
在一些特殊的环境中,你可能需要不调用它的构造器(也就是initialize)来创建一个对象。也就是说你想要创建一个空的对象.例如,假设你有一个对象,它的状态完全的由它的存取方法所确定,因此如果你不是真的想要一个另外的状态的话,调用new方法是没必要的.此时我们能allocate方法.
2 Modules
在ruby中使用Modules有两个原因.第一个原因是namespace 的管理,当我们在module中存储常量和方法时,我们将会有更少的命名冲突.调用module中的方法和类方法很类似,就是模块名+方法名.因此我们看到File.ctime 和FileTest.exist?, 时,我们从表面无法知道 File和FileTest是模块还是类.
第二个原因更有趣,我们能使用模块进行mixin.关于什么是mixin,就不说了。
一个模块也能有实例方法,当某个类include了它之后,这些实例方法就变成那个类的了。
但是如果有一个模块方法时,要怎么办。你可能认为他们被作为类方法来调用。但是ruby没有这种行为。module methods 没有被mixed in。
可是我们如果想要这样使用,我们有一个小技巧.我们可以覆盖一个叫做append_features的方法来实现模块方法的mix.看下面的例子:
这是一个非常有价值的例子.首先我们应当理解append_features 不是一个当include发生时就被调用的hook。它实际上做的是include 操作的工作.这就是为什么super方法在这里是必须的了。没有super。模块剩下的(这里是meth1 )将不会被include.
这里还要注意的是append_features里面定义了一个方法,在ruby中方法内部定义的方法只能是singleton method (也就是说要么是类方法,要么是模块方法).如果你尝试着定义一个实例方法,就会抛出一个Nested method error.
有时一个模块可能想要决定一个mixin的发起类。append_features 也可以做这个,因为它的参数就是那个类.
我们其实也可以mix一个实例方法,作为类方法:
如果我们使用extend,代码就变成这样了:
我们这里谈论的都是方法,那么实例变量呢,它能被mix吗。尽管模块拥有自己的实例数据是可能的,可是经常都不需要这样做.
mix一个模块到一个对象,也是可以操作的。后面我们会介绍.
我们可以mix Comparable模块 和定义<=> 方法。这样的话我们就能使用<, >, <=, 这样的操作.
3 转换一个对象
这张其实前面几张都有了。比如to_s和to_str的区别,比如coerce的使用。因此这边就简要的介绍下了.
看下面的例子
也就是说调用*或者+的时候会将字符串转换,而数字将不会做任何动作.
4 创建一个只有数据的类(Structs)
可能你想这样做:
虽然这样也可以做,可是他太丑陋了。在ruby中,我们有Struct 来做这个事.我们能够这样使用Struct:
那么new方法的第一个参数的意思是什么呢?当我们调用Struct.new创建一个新的structure template 时,一个新的类就通过Struct 类他自己被创建。这个类的名字就是第一个参数的内容。因此我们还能这样做:
当你创建一个structure 的实例的时候不一定要把所有的变量都写上,当你调用new时,忽略的变量,它会默认为nil。
这里的话,不要创建一个名叫Tms的Struct,因为Struct内置了一个Tms的类。
5 冻结对象
我们如果想要保护一个对象不被改变,这时我们能使用freeze 方法。
但是这里注意的是freeze 操作的是对象的引用,而不是那个变量。请看下面的例子:
这里可以看到str使用+=之后创建了一个新的对象,这时str指向了新的对象,因此新的对象并没有被冻结,而老的对象依旧被冻结了。
frozen? 方法返回一个对象是否被冻结.
在一些特殊的环境中,你可能需要不调用它的构造器(也就是initialize)来创建一个对象。也就是说你想要创建一个空的对象.例如,假设你有一个对象,它的状态完全的由它的存取方法所确定,因此如果你不是真的想要一个另外的状态的话,调用new方法是没必要的.此时我们能allocate方法.
class Person attr_accessor :name, :age, :phone def initialize(n,a,p) @name, @age, @phone = n, a, p end def test p "aaa" end end p1 = Person.new("John Smith",29,"555-1234") p2 = Person.allocate p p1.age # 29 p p2.age # nil p2.test
2 Modules
在ruby中使用Modules有两个原因.第一个原因是namespace 的管理,当我们在module中存储常量和方法时,我们将会有更少的命名冲突.调用module中的方法和类方法很类似,就是模块名+方法名.因此我们看到File.ctime 和FileTest.exist?, 时,我们从表面无法知道 File和FileTest是模块还是类.
第二个原因更有趣,我们能使用模块进行mixin.关于什么是mixin,就不说了。
一个模块也能有实例方法,当某个类include了它之后,这些实例方法就变成那个类的了。
module MyMod def meth1 puts "This is method 1" end end class MyClass include MyMod # ... end x = MyClass.new x.meth1 # This is method 1
但是如果有一个模块方法时,要怎么办。你可能认为他们被作为类方法来调用。但是ruby没有这种行为。module methods 没有被mixed in。
可是我们如果想要这样使用,我们有一个小技巧.我们可以覆盖一个叫做append_features的方法来实现模块方法的mix.看下面的例子:
module MyMod def MyMod.append_features(someClass) def someClass.modmeth puts "Module (class) method" end super # This call is necessary! end def meth1 puts "Method 1" end end class MyClass include MyMod def MyClass.classmeth puts "Class method" end def meth2 puts "Method 2" end end x = MyClass.new # Output: MyClass.classmeth # Class method x.meth1 # Method 1 MyClass.modmeth # Module (class) method x.meth2 # Method 2
这是一个非常有价值的例子.首先我们应当理解append_features 不是一个当include发生时就被调用的hook。它实际上做的是include 操作的工作.这就是为什么super方法在这里是必须的了。没有super。模块剩下的(这里是meth1 )将不会被include.
这里还要注意的是append_features里面定义了一个方法,在ruby中方法内部定义的方法只能是singleton method (也就是说要么是类方法,要么是模块方法).如果你尝试着定义一个实例方法,就会抛出一个Nested method error.
有时一个模块可能想要决定一个mixin的发起类。append_features 也可以做这个,因为它的参数就是那个类.
我们其实也可以mix一个实例方法,作为类方法:
module MyMod def meth3 puts "Module instance method meth3" puts "can become a class method." end end class MyClass class << self # Here, self is MyClass include MyMod end end MyClass.meth3 # Output: # Module instance method meth3 # can become a class method.
如果我们使用extend,代码就变成这样了:
class MyClass extend MyMod end
我们这里谈论的都是方法,那么实例变量呢,它能被mix吗。尽管模块拥有自己的实例数据是可能的,可是经常都不需要这样做.
mix一个模块到一个对象,也是可以操作的。后面我们会介绍.
我们可以mix Comparable模块 和定义<=> 方法。这样的话我们就能使用<, >, <=, 这样的操作.
3 转换一个对象
这张其实前面几张都有了。比如to_s和to_str的区别,比如coerce的使用。因此这边就简要的介绍下了.
看下面的例子
class String def coerce(n) if self['.'] [n, Float(self)] else [n, Integer(self)] end end end x = 1 + "23" # 24 y = 23 * "1.23" # 29.29
也就是说调用*或者+的时候会将字符串转换,而数字将不会做任何动作.
4 创建一个只有数据的类(Structs)
可能你想这样做:
class Address attr_accessor :street, :city, :state def initialize(street1, city, state) @street, @city, @state = street, city, state end end books = Address.new("411 Elm St", "Dallas", "TX")
虽然这样也可以做,可是他太丑陋了。在ruby中,我们有Struct 来做这个事.我们能够这样使用Struct:
Address = Struct.new("Address", :street, :city, :state) books = Address.new("411 Elm St", "Dallas", "TX")
那么new方法的第一个参数的意思是什么呢?当我们调用Struct.new创建一个新的structure template 时,一个新的类就通过Struct 类他自己被创建。这个类的名字就是第一个参数的内容。因此我们还能这样做:
Struct.new("Address", :street, :city, :state) books = Struct::Address.new("411 Elm St", "Dallas", "TX")
当你创建一个structure 的实例的时候不一定要把所有的变量都写上,当你调用new时,忽略的变量,它会默认为nil。
这里的话,不要创建一个名叫Tms的Struct,因为Struct内置了一个Tms的类。
5 冻结对象
我们如果想要保护一个对象不被改变,这时我们能使用freeze 方法。
str = "This is a test. " str.freeze begin str << " Don't be alarmed." # Attempting to modify rescue => err puts "#{err.class} #{err}" end arr = [1, 2, 3] arr.freeze begin arr << 4 # Attempting to modify rescue => err puts "#{err.class} #{err}" end # Output: # TypeError: can't modify frozen string # TypeError: can't modify frozen array
但是这里注意的是freeze 操作的是对象的引用,而不是那个变量。请看下面的例子:
str = "counter-" str.freeze str += "intuitive" # "counter-intuitive" arr = [8, 6, 7] arr.freeze arr += [5, 3, 0, 9] # [8, 6, 7, 5, 3, 0, 9]
这里可以看到str使用+=之后创建了一个新的对象,这时str指向了新的对象,因此新的对象并没有被冻结,而老的对象依旧被冻结了。
frozen? 方法返回一个对象是否被冻结.
hash = { 1 => 1, 2 => 4, 3 => 9 } hash.freeze arr = hash.to_a puts hash.frozen? # true puts arr.frozen? # false hash2 = hash puts hash2.frozen? # true
发表评论
-
一个创建闭包的小技巧
2008-06-05 00:12 2131一个小技巧,在Ola Bini 的blog上看到的。 假设你 ... -
解决Colored Cubes问题
2008-06-02 10:43 2784Engineering Puzzle You have fo ... -
ruby1.9中的Iterators
2008-03-05 22:37 3718在ruby1.9中增加了External Iterators这 ... -
一个简单的ruby Metaprogram的例子
2008-03-03 23:49 4102比如下面一个文件 people.txt 引用name,age ... -
Ruby Object Model
2008-03-03 19:29 3574刚好看到,保存一下. -
一个检测方法的参数类型的小程序
2008-03-02 22:48 3248今天没事看blog的时候,看到一个小子实现了这个,不过他的程序 ... -
rails中的BlankSlate源码分析
2008-02-28 23:27 3445其实这个类实现的功能很简单,那就是实现一个没有predefin ... -
ruby中的类变量与类实例变量
2008-02-26 21:15 7633首先,在ruby1.8中类变量是所有子类和父类共享的,可以看下 ... -
在ubuntu上共存多个版本的ruby
2008-02-24 15:20 4376今天装Revactor库的时候,真把我郁闷了,没想到ubunt ... -
看到了一个用ruby写的scheme解释器
2008-02-16 21:35 3768,自己本来想等啥时候有时间做个类似的东西呢,没想到已经有人做 ... -
ruby way之处理RSS和Atom
2008-01-31 01:32 35191 rss 标准库 RSS 是基于xml的,因此你能简单的将 ... -
ruby way之使用REXML解析xml
2008-01-30 00:35 9253REXML 是一个完全用ruby写的processor ,他有 ... -
rails2中的一些被废弃的用法
2008-01-29 00:33 2542这些只是自己最近看web开发敏捷之道的时候(由于书中的版本是1 ... -
ruby way之动态特性之二
2008-01-25 00:49 36781 得到所定义的实体的列表 ruby的反射api能够使我们在 ... -
ruby way之动态特性之一
2008-01-23 01:25 45401 动态的evaluate代码 全局的方法eval 编译并且 ... -
ruby way之高级OOP特性之二
2008-01-20 03:43 29491 把代码像对象一样存储 当你想要以对象的形式存储一块代码的 ... -
ruby way之高级OOP特性之一
2008-01-19 12:14 22631 发送一条消息给一个对象 当你调用一个方法时,你也就是发送 ... -
ruby way之OOP之一
2008-01-16 00:25 26311 使用多个构造方法 在ruby中没有像c++或者ruby中 ... -
ruby way之连接数据库
2008-01-14 00:47 2475这边都只是个大概,具体的要自己去看文档了. 1 连接SQLi ... -
ruby way之高级数据存取
2008-01-13 02:31 3732经常我们需要以一种更 ...
相关推荐
### Addison Wesley《The Ruby Way》第二版(2006年10月) #### 书籍概览 《The Ruby Way》是由Hal Fulton编写的关于Ruby编程语言的经典著作,该书的第二版出版于2006年10月,由Addison Wesley Professional出版社...
标题 "prototype_oop_javascript_ruby_prototype_" 暗示了我们将探讨的是关于原型(Prototype)面向对象编程(Object-Oriented Programming, OOP)的概念,主要关注JavaScript和Ruby这两种语言之间的相似性和差异性...
本文将深入探讨"grawing_way_oop"这一主题,它可能是一个关于使用C++进行面向对象编程的实践项目,其中涉及到CMake.txt配置文件的修改,以适应项目构建需求。 首先,我们来理解面向对象编程的核心概念。面向对象...
2.之所以说 oop 是一种思想,是因为很多编程语言对它的具体实现 上还是有较大的不同的。比如 python 中函数和变量也都是对象, Javascript 中有很多的伪对象,Java 则是完全的面向对象,而 Java 和 PHP 等语言都只能...
Ruby的块和闭包是其独特之处,它们提供了强大的控制流和数据处理能力,这是Java中匿名内部类和接口不能比拟的。 其次,Ruby的语法简洁明了,例如,方法调用可以省略括号,变量声明不需要特定关键字,这使得代码看...
在Ruby编程语言中,面向对象编程(Object-Oriented Programming, OOP)是一种核心特性,它使得代码更加结构化和可重用。"learn_oop_ruby:启动School Ruby OOP教程"是一个针对初学者的资源,旨在帮助他们掌握Ruby中的...
**OOP之UML设计模式概述** 面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它以对象为中心,强调数据和操作数据的方法,通过封装、继承和多态等特性来实现软件的模块化和可扩展性。在OOP中...
倍福OOP2_计数器程序
2. **事件监听和处理**:在Ruby中,可以定义类和对象来监听特定的事件,并定义方法作为事件处理器。例如,可以创建一个Server类,该类实例监听TCP连接请求,接收到连接事件后,调用处理连接的方法。 3. **线程和 ...
### 二、Ruby编程基础 #### 2.1 变量与数据类型 - **变量**:Ruby中的变量无需声明类型,直接赋值即可使用。例如:`name = "John Doe"`。 - **数据类型**: - 字符串(String) - 数组(Array) - 哈希(Hash) ...
- **面向对象编程(OOP)**:详细解释Ruby中的类、对象、继承、封装、多态等OOP核心概念。 - **程序结构**:探讨模块、混合和命名空间,如何组织大型Ruby项目。 #### 第二部分:进阶技巧 - **元编程**:讲解Ruby的元...
2. **封装**:封装是将数据和操作数据的方法绑定在一起的过程,保护数据不被外部直接访问。在Java中,通过使用访问修饰符(public, private, protected)来实现封装。例如,你可以将Car类的发动机型号设为私有,只...
**OOP实践** 面向对象编程(Object-Oriented Programming,简称OOP)是一种软件开发方法,它基于对象、类和消息传递的概念,旨在提高代码的重用性、可维护性和可扩展性。在实际的软件开发中,OOP是解决复杂问题的...
### Java OOP编程思想学习之我见 在深入探讨Java面向对象编程(OOP)之前,我们首先要理解OOP的基本概念及其与过程式编程的区别。Java作为一种强大的编程语言,其设计初衷之一就是全面拥抱OOP理念,这不仅体现在...
2. **面向对象编程(OOP)** - Ruby是一种纯面向对象的语言,一切皆对象。 - 类(Class)与实例(Instance)的概念。 - 继承(Inheritance)与多态(Polymorphism)。 - Ruby的元编程特性,如模块(Module)和混入(Mixins)等...
"PHP5面向对象初步(第二章).php"可能涉及封装的概念,这是OOP的四大特性之一。封装允许我们将数据和操作这些数据的方法绑定在一起,保护内部数据不受外界干扰。通过访问修饰符(如public、private、protected),...
java oop,适合小白。
2. **原型对象**:每个构造函数都有一个`prototype`属性,它是对象的原型,可以添加方法和属性。这些属性和方法将被所有该构造函数的实例共享。例如: ```javascript Person.prototype.greet = function() { ...