Ruby 开发:Gem 打包与 Ruby 实现解读
1. Ruby Gem 打包与管理
在 Ruby 开发中,Gem 是一种将代码、文档和依赖项打包的有效方式,方便代码的分发和复用。以下将详细介绍 Gem 的创建、上传以及相关注意事项。
1.1 指定依赖版本
在创建 Gem 时,可以指定特定的依赖版本或版本范围。示例代码如下:
s.add_dependency('text', '= 0.1.13')
1.2 包含可执行脚本
若 Gem 包含可执行脚本,可按以下方式指定:
s.bindir = "bin" # 指定目录
s.executables = ["spellcheck"] # 指定目录中的文件
1.3 创建 Gem 文件
当所有 Ruby 文件位于 lib 目录下, README 文件编写完成, gemspec 文件构建好后,创建实际的 Gem 文件就很简单,只需运行以下命令:
gem build document.gem
此命令将创建一个名为 document-1.0.1.gem 的文件。
1.4 安装 Gem
要在系统上安装新的 Gem,只需指定 Gem 文件:
gem install document-1.0.1.gem
1.5 上传 Gem 到仓库
如果是为开源项目创建 Gem,需要将其上传到公共仓库。以 Gemcutter 为例,操作步骤如下:
1. 访问 http://gemcutter.org 并创建免费账户。
2. 安装 gemcutter Gem:
gem install gemcutter
- 推送 Gem 到 Gemcutter 仓库:
gem push document-1.0.0.gem
1.6 自动化 Gem 创建
手动构建和上传 Gem 较为繁琐,可通过创建 Rakefile 实现自动化。示例 Rakefile 如下:
require 'spec/rake/spectask'
require 'rake/gempackagetask'
task :default => [ :spec, :gem ]
Spec::Rake::SpecTask.new do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
end
gem_spec = Gem::Specification.new do |s|
s.name = "document"
s.version = "1.0.1"
s.authors = ["Russ Olsen"]
s.date = %q{2010-05-23}
s.description = 'Document - Simple document class'
s.summary = s.description
s.email = 'russ@russolsen.com'
s.files = ['README','lib/document.rb', 'spec/document_spec.rb']
s.homepage = 'http://www.russolsen.com'
s.has_rdoc = true
s.rubyforge_project = 'simple_document'
end
Rake::GemPackageTask.new( gem_spec ) do |t|
t.need_zip = true
end
为了将最终的 Gem 文件推送到 Gemcutter,可添加以下任务到 Rakefile 底部:
task :push => :gem do |t|
sh "gem push pkg/#{gem_spec.name}-#{gem_spec.version}.gem"
end
之后,使用 rake push 即可发布 Gem。
1.7 使用 Hoe 简化 Gem 构建
Hoe 是一个流行的 Gem,可帮助自动化 Gem 构建过程。若要使用 Hoe 创建新 Gem 的目录结构,可运行以下命令:
sow document
此命令将生成 Gem 目录结构,包括 lib 和 test 目录、骨架 README.txt 文件和 Rakefile 。完成必要修改后,使用 rake gem 构建 Gem。
1.8 避免 Gem 使用中的问题
在使用 Gem 时,需注意以下问题:
- 名称冲突 :
- 类名冲突 :可将代码封装在模块中减少冲突可能性。示例:
module WordProcessor
class Font
end
class Printer
end
class Document
# ...
end
end
- **文件名冲突**:可指定本地文件的完整路径来解决。示例:
dir = File.expand_path( File.dirname(__FILE__) )
require File.join( dir, 'document' )
- 依赖管理 :确保依赖列表包含所有必需的 Gem,避免遗漏或错误包含不必要的依赖。
- 位置独立性 :编写 Gem 时,要确保其不依赖特定位置。例如,避免直接读取当前目录下的文件,可使用
__FILE__获取文件的完整路径。示例:
def read_default_font_file
File.read( "#{File.dirname(__FILE__)}/times_roman_12.font")
end
2. Ruby 主要实现版本
Ruby 有多种实现版本,不同版本在功能和性能上有所差异。以下是主要的 Ruby 实现版本介绍:
| 实现版本 | 语言支持 | 描述 |
|---|---|---|
| MRI(Matz’s Ruby Interpreter) | Ruby 1.8.7 | 由 Yukihiro Matsumoto 编写的原始 Ruby 实现,用 C 语言编写。 |
| YARV(Yet Another Ruby VM) | Ruby 1.9.X | 用于运行 Ruby 1.9 版本,待 1.8 到 1.9 过渡完成后将成为主要实现,同样用 C 语言编写。 |
| JRuby | Ruby 1.8,接近完全支持 1.9 | 基于 Java VM 的 Ruby 实现。 |
此外,还有一些不太知名或不太完整的 Ruby 实现,如 Rubinius、IronRuby 和 Cardinal。
3. MRI:C 程序员的启示
MRI 作为原始的 Ruby 实现,对于了解 Ruby 底层原理很有帮助。其源代码可从 www.ruby-lang.org 获取。解压后,顶层目录包含约 55 个 C 源文件和头文件,这些是 Ruby 解释器的核心。
3.1 代码解析与执行
MRI 将 Ruby 代码转换为抽象语法树(AST),主要由 lex.c 和 parse.y 完成。例如,对于以下 Ruby 代码:
if denominator != 0
quotient = numerator / denominator
end
MRI 会生成相应的 AST。生成 AST 后,MRI 从根节点开始递归执行,相关代码主要在 eval.c 文件中。
3.2 类的定义
大部分顶层文件遵循一致的模式,每个文件实现一个或几个相关的 Ruby 类。例如, object.c 文件底部的 Init_Object 函数定义了 Object 、 Module 和 Class 类:
rb_cObject = boot_defclass("Object", 0);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
3.3 方法实现
object.c 文件还包含许多有趣的实现,如 == 方法的默认实现:
static VALUE
rb_obj_equal(obj1, obj2)
VALUE obj1, obj2;
通过了解 MRI 的实现,C 程序员可以获得对 Ruby 运行机制的独特见解,即使不直接使用 C 语言编写代码,也有助于成为更好的 Ruby 开发者。
graph LR
A[创建 Gem 依赖] --> B[包含可执行脚本]
B --> C[创建 Gem 文件]
C --> D[安装 Gem]
D --> E{是否开源项目}
E -- 是 --> F[上传到仓库]
E -- 否 --> G[完成]
F --> H[自动化 Gem 创建]
H --> I[使用 Hoe 简化构建]
I --> J[避免使用问题]
4. YARV:Ruby 1.9 的实现
YARV(Yet Another Ruby VM)是为运行 Ruby 1.9 版本而设计的虚拟机,随着 Ruby 从 1.8 向 1.9 过渡,YARV 有望成为主要的 Ruby 实现。它同样采用 C 语言编写,具备更好的性能和优化。
4.1 改进的性能
YARV 在性能方面相较于 MRI 有显著提升。它引入了字节码编译和执行机制,将 Ruby 代码编译为字节码,然后由虚拟机执行。这种方式减少了解释执行的开销,提高了代码的执行速度。
以下是 YARV 编译和执行的简单流程:
1. 解析 :将 Ruby 代码解析为抽象语法树(AST)。
2. 编译 :将 AST 编译为字节码。
3. 执行 :虚拟机执行字节码。
graph LR
A[Ruby 代码] --> B[解析为 AST]
B --> C[编译为字节码]
C --> D[虚拟机执行字节码]
4.2 新特性支持
YARV 支持 Ruby 1.9 引入的许多新特性,如编码声明、哈希语法改进、块参数语法等。这些新特性使得 Ruby 代码更加简洁和易读。
例如,Ruby 1.9 中的哈希语法:
# Ruby 1.8 哈希语法
hash = {:key1 => 'value1', :key2 => 'value2'}
# Ruby 1.9 哈希语法
hash = {key1: 'value1', key2: 'value2'}
5. JRuby:基于 Java VM 的 Ruby 实现
JRuby 是在 Java 虚拟机(JVM)上运行的 Ruby 实现,它结合了 Ruby 的动态特性和 Java 的强大生态系统。
5.1 跨平台兼容性
由于基于 JVM,JRuby 具有良好的跨平台兼容性。可以在任何支持 Java 的操作系统上运行,无需担心底层操作系统的差异。
5.2 与 Java 互操作性
JRuby 最大的优势之一是可以与 Java 代码无缝交互。可以在 Ruby 代码中直接调用 Java 类和方法,也可以在 Java 代码中调用 Ruby 代码。
以下是在 JRuby 中调用 Java 类的示例:
# 加载 Java 类
java_import 'java.util.ArrayList'
# 创建 Java 对象
list = ArrayList.new
# 调用 Java 方法
list.add('element1')
list.add('element2')
# 输出列表大小
puts list.size
5.3 性能优化
JRuby 利用 JVM 的优化技术,如即时编译(JIT),来提高代码的执行性能。在某些情况下,JRuby 的性能甚至可以超过 MRI。
6. 其他 Ruby 实现
除了 MRI、YARV 和 JRuby 这三个主要的 Ruby 实现外,还有一些其他的 Ruby 实现,虽然不太知名或不太完整,但也有其独特的特点。
| 实现版本 | 描述 |
|---|---|
| Rubinius | 旨在成为一个自托管的 Ruby 实现,即完全用 Ruby 编写。 |
| IronRuby | 基于 .Net 平台的 Ruby 实现,类似于 JRuby 在 Java 平台上的地位。 |
| Cardinal | 运行在 Parrot 虚拟机上的 Ruby 实现,Parrot 虚拟机旨在支持多种动态语言。 |
7. 总结
Ruby 拥有多种实现版本,每种实现都有其特点和适用场景。在选择 Ruby 实现时,需要根据项目的需求、性能要求和开发环境等因素进行综合考虑。
- MRI :适合对 Ruby 底层原理感兴趣的 C 程序员,以及运行 Ruby 1.8 代码的项目。
- YARV :对于使用 Ruby 1.9 新特性和追求更好性能的项目是一个不错的选择。
- JRuby :适用于需要与 Java 代码交互或跨平台部署的项目。
同时,在开发 Ruby 代码时,合理使用 Gem 进行代码打包和管理,可以提高代码的复用性和可维护性。通过自动化工具和避免常见问题,可以更高效地开发和发布 Ruby 项目。
总之,了解不同的 Ruby 实现和 Gem 管理技巧,有助于成为一名更优秀的 Ruby 开发者,能够根据具体情况选择最合适的工具和技术,开发出高质量的 Ruby 应用程序。
超级会员免费看
901

被折叠的 条评论
为什么被折叠?



