directory search
Ruby用户指南 3、开始 4、简单的例子 5、字符串 6、正则表达式 7、数组 8、回到那些简单的例子 9、流程控制 10、迭代器 11、面向对象思维 12、方法 13、类 14、继承 15、重载方法 16、访问控制 17、单态方法 18、模块 19、过程对象 20、变量 21、全局变量 22、实变量 23、局部变量 24、类常量 25、异常处理:rescue 26、异常处理:ensure 27、存取器 28、对象的初始化 29、杂项 RGSS入门教程 1、什么是RGSS 2、开始:最简单的脚本 3、数据类型:数字 4、数据类型:常量与变量 5、数据类型:字符串 6、控制语句:条件分歧语句 7、控制语句:循环 8、函数 9、对象与类 10、显示图片 11、数组 12、哈希表(关联数组) 13、类 14、数据库 15、游戏对象 16、精灵的管理 17、窗口的管理 18、活动指令 19、场景类 Programming Ruby的翻译 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 类,对象和变量 容器Containers,块Blocks和迭代Iterators 标准类型 深入方法 表达式Expressions 异常,捕捉和抛出(已经开始,by jellen) 模块 基本输入输出 线程和进程 当遭遇挫折 Ruby和它的世界 Ruby和Web开发 Ruby Tk Ruby 和微软的 Windows 扩展Ruby Ruby语言 (by jellen) 类和对象 (by jellen) Ruby安全 反射Reflection 内建类和方法 标准库 OO设计 网络和Web库 Windows支持 内嵌文档 交互式Ruby Shell 支持 Ruby参考手册 Ruby首页 卷首语 Ruby的启动 环境变量 对象 执行 结束时的相关处理 线程 安全模型 正则表达式 字句构造 程序 变量和常数 字面值 操作符表达式 控制结构 方法调用 类/方法的定义 内部函数 内部变量 内部常数 内部类/模块/异常类 附加库 Ruby变更记录 ruby 1.6 特性 ruby 1.7 特性 Ruby术语集 Ruby的运行平台 pack模板字符串 sprintf格式 Marshal格式 Ruby FAQ Ruby的陷阱
characters

Ruby和微软的Windows



Ruby 的实现是基于 POSIX环境的,也就是说它可以利用unix程序员熟悉的所有的系统调用和系统库。

同时,系统设计的时候扩展了对windows的支持,这章,我们将看看这方面的特性,并展示一些在windows下高效使用ruby的秘诀。

Ruby Ports

Windows does not provide a POSIX environment by itself, so some sort of emulation library is required in order to provide the necessary functions. There are several ports of Ruby for Windows: the most commonly used one relies on the GNU Win32 environment, and is called the ``cygwin32'' port. The cygwin32 port works well with extension libraries, and is available on the Web as a precompiled binary. Another port, ``mswin32,'' does not rely on cygwin. It is currently available as source code only. The remainder of this chapter will refer to the cygwin32 port.

在 Windows下运行Ruby

cygwin32版本的ruby发布包括两个可执行文件:ruby.exe ,rubyw.exe

ruby.exe 用在命令提示符下(dos shell),就像unix版本中的一样。对于需要从标准输入输出进行读写操作的应用来说比较适合,但是这样的话我们运行什么程序都需要额外多开了一个窗口,而不管我们需不需要这个窗口,有时候这样就显得不合适了,比如我们双击一个ruby脚本运行一个图形接口(比如Tk),或者作为后台程序运行,或者在别的程序中被调用。
在这种情况下,我们可以用rubyw.exe ,他和 ruby.exe 一样,但是不提供标准输入和标准输出,或者标准错误,并且不会打开一个dos shell的窗口。

可以对ruby脚本(.rb结尾的文件)设定文件关联[在用菜单 查看/选项/文件类型],然后双击这个文件就可以调用rubyw.exe来执行这个程序了。

Win32API

如果你的ruby程序打算直接访问win32api,或者用一些DLL的入口点,你将会用到Win32API扩展。

你可以用要访问的DLL名字创建一个Win32API对象,表示对一个指定的DLL的入口点的调用,DLL的名字包括函数,函数签名(参数和返回值),建立的win32api对象就可以用来对指定的dll进行调用。

DLL的很多参数都是一定形式的二进制结构,Win32API用ruby的字符串对象处理这些参数,进行来回的传递。你需要对这些字符串进行打包和解包(pack and unpack)

Windows Automation

如果你对使用低层次的windows API调用不感兴趣,你可以使用windows utomation,ruby可以当成Windows Automation 的客户。感谢 Masaki Suketa写的 win32OLE扩展。下面例子是WIN32OLE发布包中提供的。

Windows 自动化允许自动化控制器(客户端)向自动化服务器(Excel, Word, PowerPoint等)发送一个命令或者进行查询。

你可以向WIN32OLE发送一个命令,从而可以执行自动化服务器上具有相同名字的方法。例如,你可以创建一个WIN32OLE客户,创建几个全新的IE浏览器,并且显示ie设置的主页:

ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
ie.gohome

WIN32OLE并不知道这些方法(比如visiblegohome),它会把这些向它调用的方法传到WIN32OLE#invoke,在这个方法里向自动化服务器发送正确的命令。

读、写自动化服务器的属性

你可以用通常的哈希表示方法从自动化服务器读写服务器的属性。比如,可以如下面一样设定一个Excel chart的Rotation的值:

excel = WIN32OLE.new("excel.application")
excelchart = excel.Charts.Add()
...
excelchart['Rotation'] = 45
puts excelchart['Rotation']

OLE对象的参数自动都会被设成属性,也就是说你可以你可以通过给一个属性赋值而设定一个参数。

excelchart.rotation = 45
r = excelchart.rotation

因为这些属性是常规的ruby访问方法,而属性名不能以大写字母开头,所以你要用rotation而不是Rotation

命名参数(Named Arguments)

其他的能实现自动化客户端的语言,比如VB,有一种叫做命名参数(named arguments)的概念,假设我们有这样的一个VB方法:

Song(artist, title, length):    rem Visual Basic

要想调用这个方法,除了按顺序写全这三个参数来调用之外,我们可以用命名参数的方法:

Song title := 'Get It On':      rem Visual Basic

这等同于调用 Song(nil, 'Get It On', nil)
在Ruby中,可以在调用的时候用哈希结构来指定参数名和它的值,比如:

Song.new( 'title' => 'Get It On' )

for each方法

VB有一个方法 ``for each''语句,可以在服务端对一个集合进行迭代, WIN32OLE对象也有一个方法完成相同的作用。

一个例子

下面这个例子,用到了微软的Excel,覆盖了上面说的很多概念。首先,我们创建了一个新的基于Excel的WIN32OLE对象,并增加了一些单元格,并给这些单元格赋值。然后,我们选中了一个区域,并创建了图表(chart),我们通过给这个图表的type属性赋值,使它成为一个3D的图表。然后,

The following example, using Microsoft Excel, illustrates most of these concepts. First, we create a new object attached to Excel and set some cell values. Next we select a range of cells and create a . We set the Type property in the excelchart object to make it a 3D chart. Next we'll loop through and change the chart rotation, 10?at a time. We'll add a few charts, and we'll use each to step through and print them out. Finally, we'll close down the Excel application and exit.

require 'win32ole'

# -4100 is the value for the Excel constant xl3DColumn. ChartTypeVal = -4100;

# Creates OLE object to Excel excel = WIN32OLE.new("excel.application")

# Create and rotate the chart

excel['Visible'] = TRUE; workbook = excel.Workbooks.Add(); excel.Range("a1")['Value'] = 3; excel.Range("a2")['Value'] = 2; excel.Range("a3")['Value'] = 1; excel.Range("a1:a3").Select(); excelchart = workbook.Charts.Add(); excelchart['Type'] = ChartTypeVal;

30.step(180, 10) do |rot|     excelchart['Rotation'] = rot end

excelchart2 = workbook.Charts.Add(); excelchart3 = workbook.Charts.Add();

charts = workbook.Charts charts.each { |i| puts i }

excel.ActiveWorkbook.Close(0); excel.Quit();

优化

As with most (if not all) high-level languages, it can be all too easy to churn out code that is unbearably slow, but that can be easily fixed with a little thought.

WIN32OLE来说, 我们要避免不必要的动态查找(dynamic lookups)。如果可能,尽量把WIN32OLE对象 赋给一个变量,然后引用这个变量的元素,而不要使用一大串的"." 构成的表达式。

比如,我们不应该写出这样的代码:

workbook.Worksheets(1).Range("A1").value = 1
workbook.Worksheets(1).Range("A2").value = 2
workbook.Worksheets(1).Range("A3").value = 4
workbook.Worksheets(1).Range("A4").value = 8

我们可以通过把这些语句的前面部分放到一个临时变量里,而使用临时变量来执行方法。

worksheet = workbook.Worksheets(1)

worksheet.Range("A1").value = 1 worksheet.Range("A2").value = 2 worksheet.Range("A3").value = 4 worksheet.Range("A4").value = 8


Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright © 2001 by Addison Wesley Longman, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/)).

Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.

Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.
Previous article: Next article: