Verzeichnis suchen
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的陷阱
Figuren

Ruby a和 Web



Ruby对互联网来说并不陌生,不只是因为你可以用它来写SMTP服务器,FTP服务器,或者web服务器,你还可以用它来完成通常的任务,比如CGI编程或者作为PHP的一个替代品。

编写 CGI 脚本

你可以用Ruby轻松的编写CGI脚本,为了让Ruby脚本产生HTML输出,你只需要这样做:

#!/usr/bin/env ruby
print "HTTP/1.0 200 OK\r\n"
print "Content-type: text/html\r\n\r\n"
print "<html><body>Hello World!</body></html>\r\n"

你可以用Ruby的正则表达式来解析输入字符串,查询环境变量,检查标记,填充模板,转义(escape )特殊字符,格式化HTML,然后输出。

或者,你可以用类CGI。

 

使用cgi.rb

类CGI主要来帮助你更方便的编写CGI脚本,使用它,你可以操纵表单(form),cookies和环境变量,维护有状态的session等等。关于它的文档在第497页,但是我们在这里要先看一下它大体的功能。

 

引用(Quoting)

当处理URL和HTML的时候,我们必须注意对一些特殊字符的引用。比如,一个斜线 (``/'') 在URL里有特殊意义,如果它不是URL的路径名称的一部分,那么它必须被转义(escaped)。也就是说,它在URL中将被转换为 ``%2F'',而且反过来你要想使用它,必须把它再转换为斜线。空格和and符号("&")也是特殊字符。为了处理这样的情况,CGI提供了方法 CGI.escapeCGI.unescape

require 'cgi'
puts CGI.escape( "Nicholas Payton/Trumpet & Flugel Horn" )
结果:
Nicholas+Payton%2FTrumpet+%26+Flugel+Horn

类似的,你也许需要对HTML中的特殊字符进行转义(escape ):

require 'cgi'
puts CGI.escapeHTML( '<a href="/mp3">Click Here</a>' )
结果:
&lt;a href=&quot;/mp3&quot;&gt;Click Here&lt;/a&gt;

而且,你也可以只对HTML的一部分标记进行转义,而不是全部:

require 'cgi'
puts CGI.escapeElement('<hr><a href="/mp3">Click Here</a><br>','A')
produces:
<hr>&lt;a href=&quot;/mp3&quot;&gt;Click Here&lt;/a&gt;<br>

这里又有A标记被转义了,其它标记都没有变化。

每个这样的转义方法都有一个un-开头的版本,来恢复这个转义之前的字符串。

表单(Forms)

使用CGI类你有两种方法访问HTML传过来的参数。比如我们有一个URL/cgi-bin/lookup?player=Miles%20Davis&year=1958,你可以用CGI#[ ]方法直接访问player和year变量:

require 'cgi'
cgi = CGI.new
cgi['player'] ? ["Miles Davis"]
cgi['year'] ? ["1958"]

或者,你可以把所有参数放入一个Hash中,再从这个哈希查询参数。

require 'cgi'
cgi = CGI.new
h = cgi.params
h['player'] ? ["Miles Davis"]

创建窗体(Forms)和 HTML

CGI类包含了很多产生HTML的方法,每个HTML标记都有一个方法。为了使用这些方法,你首先要创建一个CGI对象,这可以通过CGI.new方法。这个方法可以接收一个参数表示HTML的级别。比如,我们这里用了html3。

为了使得这些标记嵌套方便,这些方法都接受一个block作为来处理内容,这个block返回一个字符串,这也是这个tag的内容。比如下面的例子,我们加入了一些换行是为了能适应屏幕,能使得它被很好的显示而已。

require "cgi"
cgi = CGI.new("html3")  # add HTML generation methods
cgi.out{
  cgi.html{
    cgi.head{ "\n"+cgi.title{"This Is a Test"} } +
    cgi.body{ "\n"+
      cgi.form{"\n"+
        cgi.hr +
        cgi.h1 { "A Form: " } + "\n"+
        cgi.textarea("get_text") +"\n"+
        cgi.br +
        cgi.submit
      }
    }
  }
}
produces:
Content-Type: text/html
Content-Length: 302
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD>      
<TITLE>This Is a Test</TITLE></HEAD><body>      
<FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">      
<HR><H1>A Form: </H1>      
<TEXTAREA NAME="get_text" ROWS="10" COLS="70"></TEXTAREA>      
<BR><INPUT TYPE="submit"></FORM></body></HTML>
 

这段代码将产生一个HTML文档,主题(title)为“This Is a Test”,然后一个水平线,然后是一个header,一个测试的输入框,一个提交按钮。当接收到这个提交的页面,你会得到一个变量名为get_text,其值为你输入的文本。

Cookies

你可以通过使用cookies在客户机上存放各种有用的信息,你可以创建一个有名字的cookie,并且设定一个指定的值。为了将这个cookie发送到浏览器,你需要在CGI#out中设置cookie 头(header)。

require "cgi"
cookie = CGI::Cookie.new("rubyweb", "CustID=123", "Part=ABC");
cgi = CGI.new("html3")
cgi.out( "cookie" => [cookie] ){
  cgi.html{
    "\nHTML content here"
  }
}
produces:
Content-Type: text/html
Content-Length: 86
Set-Cookie: rubyweb=CustID%3D123&Part%3DABC; path=

 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>       
HTML content here</HTML>
   

当用户下次访问这个页面时,你可以取得cookie CustIDPart,然后将它们显示在HTML输出中。

require "cgi"
cgi = CGI.new("html3")
cgi.out{
  cgi.html{
    cgi.pre{
      cookie = cgi.cookies["rubyweb"]
        "\nCookies are\n" + cookie.value.join("\n")
    }
  }
}
produces:
Content-Type: text/html
Content-Length: 111


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><PRE>       
Cookies are       
CustID=123       
Part=ABC</PRE></HTML>
  

Sessions

cookies需要我们进行一些人为处理后才变得有用,我们真正需要的是一个session:web客户端的持久性的状态。session在Ruby中用 CGI::Session处理,它也使用了cookie,但是提供了一个高层次的接口。

 
require "cgi"        
require "cgi/session"
 
cgi = CGI.new("html3")        
sess = CGI::Session.new( cgi, "session_key" => "rubyweb",        
                          "session_id"  => "9650",        
                          "new_session" => true,        
                          "prefix" => "web-session.")        
sess["CustID"] = 123        
sess["Part"] = "ABC"
 
cgi.out{        
  cgi.html{        
    "\nHTML content here"        
  }        
}
    

这将给用户rubyweb发送一个cookie,它的值为9650。它也会在服务器的上建立一个文件$TMP/web-session.9650,以“键-值”(key-value)的方式保存着CustID和Part的值。

当这个用户又访问这个网站时,你需要一个参数指明session id。在这个例子里应该是rubyweb=9650,然后,你就可以取得所有和这个sesion相关的数据了。

require "cgi"
require "cgi/session"

cgi = CGI.new("html3")         
sess = CGI::Session.new( cgi, "session_key" => "rubyweb",         
                               "prefix" => "web-session.")         
cgi.out{         
  cgi.html{         
    "\nCustomer #{sess['CustID']} orders an #{sess['Part']}"         
  }         
}
 

将Ruby嵌入HTML

到目前为止我们已经看过了用Ruby创建HTML文件和显示它,下面我们来看看如何将Ruby嵌入HTML文档中。

有好几个包支持我们将Ruby嵌入其它文档中,特别是HTML页面,一般来说,这叫做eRuby,它的实现也有好几种,比如eruby和erb。下面的部分将介绍eruby。

将Ruby脚本嵌入HTML非常有用,我们不仅能像ASP,JSP,PHP一样使用它,而且还能发挥Ruby的力量。

使用eruby

eruby 简单来说就像一个过滤器,对于输入的文件中的普通HTML内容,它将不会做什么处理,而对下面的格式的代码进行特殊处理:

 

表达式 意义
<% ruby code %> 将定界符内的Ruby代码转换为它的结果输出
<%= ruby expression %> 输出这个表达式的值到HTML中
<%# ruby code %> 代码注释,这些内容将被忽略。对测试来说可能有用。

调用eruby的方法如下:

eruby [
            options
            ] [
            document
            ]

如果document忽略,则eruby将从标准输入读取。eruby的命令行参数如下:

 
Option Description
-d, --debug 设置$DEBUG 为 true.
-K kcode 指定不同的编码系统(coding system 参见137页)
-M mode 指定运行模式,为下面之一:
f 过滤模式
c CGI 模式(将错误打印为HTML, 设置$SAFE=1)
n NPH-CGI 模式(打印额外的头部为HTTP,设置$SAFE=1)
-n, --noheader 禁止CGI头部( header)输出
-v, --verbose 允许详细(verbose )模式
--version 打印出版本信息并退出程序

让我们来看一些简单的例子,假如我们给eruby运行时候的输入为下面的内容:

This text is <% a = 100; puts "#{a}% Live!" %>

eruby 将把<%和%>之间的Ruby代码换成它执行后的值然后显示出来。
This text is 100% Live!

使用 <%= 的形式,直接将后面的表达式的值输出,比如,我们的输入如下:

<%a = 100%>This text is almost <%=a%> degrees! Cool!

将=a替换为a的实际值,如下:
This text is almost 100 degrees! Cool!

当然,你也可以将Ruby嵌入更复杂的文档,比如HTML。

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>eruby example</title>
</head>
<body>
<h1>Enumeration</h1>
<ul>
<%(1..10).each do|i|%>
  <li>number <%=i%></li>
<%end%>
</ul>
<h1>Environment variables</h1>
<table>
<%ENV.keys.sort.each do |key|%>
  <tr>
    <th><%=key%></th><td><%=ENV[key]%></td>
  </tr>
<%end%>
</table>
</body>
</html>

在 Apache中安装eruby

你可以安装一个使用eRuby的Apache服务器来自动解析嵌入Ruby的文档,就像PHP那样。你可以将嵌入Ruby的文档命名为以`.rhtml'' 为后缀,然后设置web服务器来调用eruby来解析这些文件输出想要的HTML。

为了在Apache中使用eruby,需要以下几步。

 

  • 将可执行的 eruby 程序拷贝到 cgi-bin 目录

  • httpd.conf 文件中增加如下两行:

    AddType application/x-httpd-eruby .rhtml
    Action application/x-httpd-eruby /cgi-bin/eruby
    

  • 如果需要,你可以在你的 DirectoryIndex 指令中加入 index.rhtml,这样,如果你的目录下面如果没有index.html文件,则就会使用index.rhtml文件作为index页。比如下面的例子

    DirectoryIndex index.html index.shtml index.rhtml
    

    当然,你也可以用一个作用于一个全站点范围的Ruby脚本

    Of course, you could also simply use a site-wide Ruby script as well.

    DirectoryIndex index.html index.shtml /cgi-bin/index.rb
    

就是如此,你可以在HTML文档中加入嵌入的Ruby脚本来动态地创建表单和内容。但也请你阅读一下从497页开始的CGI库。

提高性能

你可以使用Ruby为web编写CGI程序,但是,如同其它CGI程序一样,默认得设置下,对每个cgi页面的请求都将产生一个新的Ruby进程,这将占用服务器很多的资源,而且容易引起性能的下降。Apache web服务器通过使用可装载的模块来解决这个问题。

一般来说,这些模块都会动态的被载入,而且会成为Web服务器进程的一部分,也就是说不需要每次有CGI请求进来都产生一个Ruby解释器程序,Web服务器就充当了解释器的角色。

所以我们会用到mod_ruby,它会将Ruby解释器连接(links)到Web服务器,关于它的具体信息可以看它的发布程序附带的README文件。

一旦你安装配置好之后,你就可以像原来一样运行Ruby脚本,不同的是现在地速度应该是快很多了。


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.
Vorheriger Artikel: Nächster Artikel: