`
javasogo
  • 浏览: 1775441 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

[转载]ruby 动态性

阅读更多
谈到 Java™ 语言的类型方法时,Java 社区分为两大阵营。一些人喜欢编译时错误检查,更好的安全性,以及改善的工具 —— 这些都是静态类型所能提供的特性。而另一些人则偏爱更动态的类型体验。这一次在 跨越边界 中,您将看到两种高生产力的非 Java 语言所使用的一些截然不同的 类型策略 ,并发现在 Java 编程中提高类型灵活性的一些方法。

在对任何编程语言的讨论中,争议较大的一个问题就是类型模型。类型决定可以使用哪些种类的工具,并影响到应用程序的设计。很多开发人员将类型与生产率或可维护性联系起来(我就是其中的一个)。典型的 Java 开发人员通常都特别乐于维护 Java 语言的类型模型的地位,强调 Java 语言可采用更好的开发工具,在编译时捕捉某些种类的 bug(例如类型不兼容和拼写错误),以及性能等方面的优势。

如果您想理解一种新的编程语言,甚至一系列语言,那么通常应该从类型策略着手。在本文中,您将看到 Java 之外的一些语言中的类型模型。我首先简要介绍任何语言设计者在类型模型中必须考虑的一些决策,着重介绍静态类型和动态类型的一些不同的决策。我将展示一些不同极端的例子 —— Objective Caml 中的静态类型和 Ruby 中的动态类型 。我还将谈到 Java 语言的类型限制,以及如何突破 Java 类型的限制快速编程。

类型策略

至少可以从三个角度来看待类型:
  • 静态类型还是动态类型,这取决于何时 实施类型模型。静态类型语言在编译时实施类型。而动态类型语言通常基于一个对象的特征在运行时实施类型。
  • 强类型还是弱类型,这取决于如何 实施类型模型。强类型严格地实施类型,如果发现有违反类型规则的情况,则会抛出运行时或编译时错误。而弱类型则留有更多的余地。极端情况下,弱类型语言(例如 Assembler)允许将任意数据类型赋给另一种类型(不管这种赋值是否有意义)。静态类型的语言既可以有强类型,也可以有弱类型;而动态类型系统通常是强类型的,但也不完全是。
  • 显式类型还是隐式类型,这取决于语言如何确定一个给定对象的类型。显式类型语言要求声明每个变量和每个函数参数。而隐式类型语言则根据语言中的语法和结构线索来确定对象的类型。静态类型语言通常是显式类型的,但也不完全是;而动态类型语言几乎都是隐式类型的。
动态类型的优点

Ruby 专家 Dave Thomas 将动态类型称作duck typing(见参考资料),这有两层意思。第一层意思是说,这种语言不真正实现类型 —— 它利用鸭子理论 解决这个问题。第二层意思是说,如果什么东西走起来像鸭子,叫起来也像鸭子,那么它很可能就是一只鸭子。在编程语言的上下文中,duck typing 意味着如果一个对象对于某种类型的方法有反应,那么事实上就可以把它看作那种类型。这样的特性可以导致一些有趣的优化。

大多数偏爱动态类型的开发人员除了强调早期错误检测会带来不必要的成本外,还提到动态类型语言具有很好的可表达性和生产率。很简单,您通常可以用更少的关键词表达更多的思想。作为一名新的 Ruby 拥护者,我深信动态语言更能提高生产率,虽然我不能比常见的静态语言的支持者拿出更多具体的证据来。但是,从我开始编写更多的 Ruby 代码起,我就感觉到自己的生产率有了明显的提高。诚然,我仍然会看到静态类型的优点,尤其是在工具集方面,但是我逐渐认识到了静态类型的缺点。

当我开始用 Ruby 编写代码时,我受到的最大改变是产生和使用元编程结构的能力。如果您从头开始一直关注跨越边界 系列统的话,您就知道元编程,或者说编写用于编写程序的程序,是 Ruby on Rails 的一大推动力量,更一般地说,是特定于领域的语言的一大推动力量。用 Ruby 编程时,我通常会编写更大的构建块,或者用更大的块进行构建。我发现,与使用 Java 编程相比,我可以用更多类型的可重用块扩展我的程序。就像在 Java 编程中,您可以用新的类来扩展程序。还可以添加方法和数据到已有的类中,因为类是开放式的。您可以使用 mix-in(后面 运行时绑定 会讲到)来添加核心功能到已有的类中。还可以在任何时候根据需要改变一个对象的定义。我还是一名 Ruby 编程新手,这些功能用到的不多,但是当我真正开始使用它们时,结果令人大吃一惊。

安全性还是灵活性

从某种意义上说,语言的静态与动态之争的关键在于安全性与灵活性之间的取舍。静态语言的支持者相信更安全的语言更好。而动态语言的支持者却不愿意为安全性付出任何代价。对于他们而言,对一种语言的衡量标准在于能多快地表达思想,目标在于最大化程序员的效率。而另一方面,静态语言专家则说,如果能 在早期捕捉到 bug,那么就应该 这么做,而且工具可以弥补语言中的限制。

在动态语言,例如 Ruby 中,解决方案就截然不同。首先,我倾向于使用一个 mix-in 来实现持久性。所有关联只在 mix-in 中发现一次。可以把一个 mix-in 想像成一个接口,其背后有一个实现。换句话说,通过 mix-in,可以添加多个功能到同一个对象中,而不必使用多重继承。实际上,Active Record 通过继承一个公共基类来解决这个问题,这个公共基类混合了多种功能:

class Pojo < ActiveRecord::Base


在 Ruby 中,您不必关心继承,因为使用开放的类(允许动态添加功能)和模块(允许混入其他功能),您可以随意添加更多的功能到对象中。


Dynamic Productivity with Ruby
A Conversation with Yukihiro Matsumoto, Part II
by Bill Venners
November 17, 2003

http://www.artima.com/intv/tuesday.html

Changing Interfaces at Runtime

Single Inheritance and Mix-Ins

Productivity, Efficiency, and Robustness

用Ruby实现软件开发的动态生产力--Yukihiro Matsumoto的对话

撰文 Bill Venners 翻译:曾毅

最后更新:2003年9月17日

摘要

Ruby程序设计语言的发明人Yukihiro Matsumoto与Bill Venners进行了一次谈话。谈话内容集中讨论了变体接口,使用混合插入(mix-ins),以及Ruby的简明性给软件生产力带来的效益。

在网络上以昵称"Matz,"著称的Yukihiro Matsumoto是Ruby程序设计语言的发明人。Ruby是一种适于开发日常脚本以及完整的应用程序的面向对象程序设计语言。Matz自从1993年就开始进行了Ruby语言的研发工作。因为他想发明一种语言使得你既能非常高效的进行开发又感觉到乐趣无穷。最开始Ruby只是在日本非常流行,随后便踏上了进入了全世界程序设计者心扉的道路上。

200年9月24日Bill Venners与Yukihiro Matsumoto在丹麦Aarhus 举行的JAOO会议上会面。在这次会面上,Yukihiro Matsumoto讨论了Ruby的设计哲学,Ruby程序设计语言的特性,以及如何才能成为一个更好的程序员。在这部分当中,Matz特别介绍了设计的不完善性哲学,最小非预期理论,以及人在计算机发展上起到的重要作用。



在“运行时”改变接口

Bill Venners:在Ruby当中,我可以为对象实时的添加方法和变量。我当然已经在其他的语言当中尝试为类添加了方法和变量,这些方法和变量在运行时变成了对象。但是比如说在Java当中,一旦一个类被加载或者一个对象被实例化后,他的接口就变得不可更改了。允许结构在运行时可以修改使我有点害怕。我对于我在Ruby当中如何使用这样的特性表示非常好奇。在运行时添加方法的益处是什么呢?

Yukihiro Matsumoto:首先,你不是一定要使用这个特性。最为常用的动态特性的应用,例如为对象添加方法,是“过程中”程序设计。这样的特性使你可以建立一个适应环境的库,这些不是为特殊使用设计的。

Bill Venners: 能否举例说明什么是适应环境的库么?

Yukihiro Matsumoto:一个形象的例子是“代理”。在Ruby中,并不是为每一个特殊的类单独设计代理类,取而代之的是:你可以创建一个多用途的代理,它可以用来包装任何的对象。代理可以检测到其中的对象,并且会为那个对象在代理中作变型。代理能够为自己添加方法,所以他同包装类有相同的接口,每一个方法都可以托管给包装类当中相应的方法。所以一个可以用于包装任何对象的多功能代理是一个库中的类如何适应环境变化的形象的例子。

在Ruby中为对象添加方法同样可以被用于Java程序设计者使用内建类的情况下。例如,如果你想为某个方法传递一个监听对象,在Java中你通常是实例化一个内建类,这个内建类定义了监听器方法并传递它。在Ruby中,你可以仅仅创建一个简单的对象—一个类的对象实例—为之动态的添加所需的监听器方法并传递它。

同时,由于你可以替换一个方法并且也可以添加一个方法,你可以使用这个特性来定义回收信号。例如,每一个面向对象的图形用户界面库都有一个按钮(Button)对象。当某个人点击按钮,按钮点击方法就被调用了。在Button基类当中,这个点击方法的实现当然是空的。在别的程序设计语言中为按钮添加行为,你通常是创建一个Button的子类重载点击方法。但是在Ruby中,如果你想,你可以在Button类中直接替换点击方法。
单继承与混合插入(Mix-Ins)

Bill Venners:在你的一篇文章中曾经写道:“Ruby只支持单继承,我把它作为一个Ruby的一个特性。”为什么单继承是值得你考虑的呢?混合插入又是什么?

Yukihiro Matsumoto:单继承是非常优秀的,整个类继承结构形成了一颗单树根结点的单叉树,叫做对象,这是非常容易理解的。在一些支持多继承的程序设计语言当中,类形成了一个网络,这样反而难以理解。

虽然单继承具有简单的树形结构,使得他非常地优秀,但是有时我们会想在单继承的限制外类之间共享要素或者方法。Java在这种情况下必须定义一个接口来共享方法签名,通常是使用某种从一个对象到另一个对象的托管。在Ruby当中,我们定义了一个叫做“模”的东西,看起来很像类,但有很多的限制:即是你不能为模创建实例,模不能从类继承得到。所以在Ruby当中,如果你定义了一个具有方法的模并且将这个模插入了类当中,这样累就具有了这些方法,包括签名和实现。如果你这时将同样的模插入到另外一个类当中,就会有两个类来共享这个实现。这赋予了多继承相当多的益处,同时又没有破坏单继承简单的树形模式。

这种插入模的方法被称为“混合插入(Mix-ins)”。混合插入最初是从LISP语言文化中开始的,是作为多继承的一个使用。事实上,一个混合插入是一个使用多继承的精确手段。所以在LISP当中使用多继承是一种象征。而在Ruby当中,我们通过支持类和模强制你使用混合插入。

http://www.chinaitpower.com/A/2002-02-13/13751.html




动态语言
维基百科,自由的百科全书
跳转到: 导航, 搜索

动态语言就是一种在运行时可以改变其结构的语言:例如新的函数可以被引进,已有的函数可以被删除等在结构上的变化。众所周知的ECMAScript(JavaScript)便是一个动态语言,除此之外如Ruby、Python等也都属于动态语言,而C、C++等语言则不属于动态语言。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics