工作日即将结束。你和你的另一半预订了晚餐,所以你很想回家。就在这时,邮件来了。
“我需要在明天与高管的会议中再包含一份报告,”邮件中写道。“我附上了一些电子表格。你能帮我写点东西来计算[不相关的、晦涩的商业术语]吗?”
你开始思考完成这项工作需要什么。如果你只懂 C# 或 Java 这样的编译型语言,那么列表可能是这样的:
- 创建一个新的项目文件夹。
- 创建一个源文件。
- 想出一个类名(即使你稍后会把它扔掉)。
- 输入类定义(或者让你的 IDE 为你做)。
- 编写你的代码。
- 编译你的代码。
- 运行你的代码。
……这还是假设你第一次就做对了,并且不必修改、重新编译和重新运行几次。现在,你可能正在考虑取消晚餐。
但如果你碰巧懂一门解释型语言,比如 Ruby,那么列表会短得多:
- 创建一个源文件。
- 编写你的代码。
- 运行你的代码。
你不需要项目文件夹,因为没有编译后的类文件需要跟踪(只有你的源文件)。你不需要类名或定义,因为 Ruby 允许你在类外部编写代码(如果你想这样做)。你可能需要修改和重新测试几次,但每次尝试之间都不会有编译步骤。只是少了……繁文缛节。这意味着你的简单任务将更快完成。
快速入门:“Hello, world”
即使在一个简单的 “Hello, world” 程序中,你也能看到差异。这是 C# 中代码的样子:
public class Hello
{
public static void Main()
{
System.Console.WriteLine("Hello, World");
}
}
将其与 Ruby 程序进行比较,以执行相同的操作:
puts "Hello, World"
没错,只有一行!没有类定义,没有方法,只有你需要的代码。
我不想暗示你不能在 Ruby 中创建类和对象;事实上,这是大多数 Ruby 代码的编写方式。但是你不需要被迫为简单的问题使用这种风格。该语言不妨碍你,让你按照你想要的方式编码。
访问器
这是 Ruby 中另一个更简单的常见操作:属性访问器。普遍接受的最佳实践是不直接从类外部访问对象的实例变量。相反,你需要设置访问器方法来帮助确保适当的封装。(事实上,与大多数面向对象语言不同,Ruby 不允许你直接访问实例变量。这样更安全。)
如果我们有一个 Person 类,其中有一个 name 实例变量,我们需要设置一个方法来读取 name 的值,另一个方法来写入它。这是 Java 中代码的样子:
public class Person {
// Set up an instance variable.
private String name;
// Set up a reader method.
public String getName() {
return name;
}
// Set up a writer method.
public void setName(String name) {
this.name = name;
}
}
现在,让我们看看 Ruby 版本:
class Person
# Set up reader and writer methods for @name.
attr_accessor :name
end
当你在 Ruby 类的正文中调用 attr_accessor 方法,并将一个符号(即 :name)传递给它,其中包含你要创建的属性时,它将自动为你设置一个读取器方法、一个写入器方法和一个实例变量——所有这些都只需一行代码。
另外,请注意,虽然我们在 Java 示例中必须为实例变量和访问器方法声明类型 (String),但我们在 Ruby 中不必这样做。这是因为与许多编译型语言不同,Ruby 不进行类型检查。Ruby 只是相信你知道给定变量中存储的对象类型,并且只会调用适合该对象的方法。(如果你不这样做,你会在运行时收到错误。但在实践中,这种情况并不经常发生。)
这些都是小的便利,但想象一下它们将在大型项目中为你节省多少编码!
开源优势
Ruby 是在开源许可证下发布的——该许可证允许在专有软件中使用。当然,这带来了各种各样的好处。然而,最切实的好处是,它可以自动、随时、免费地下载、编译和安装在任何需要的服务器上。
Ruby 社区也强烈倾向于为他们发布的库使用开源许可证。成千上万个涵盖各种任务的库已准备好在你的项目中使用。安装也是自动的,这要归功于 RubyGems 包管理系统。
以下是更多 Ruby 加速开发的示例:
- 想要将几个字符串组合成一个字符串? 在 Java 或 C# 中,你可能需要创建 StringBuilder 类 的单独实例。在 Ruby 中,你需要的方法就在 字符串对象 上。
- 想要查看字符串是否与正则表达式匹配? 在大多数其他语言中,正则表达式不是一等公民。你必须创建一个包含你想要的模式的字符串,然后将该模式编译成正则表达式对象,最后将该对象与原始字符串进行比较。Ruby 可以在 一步 中完成;你只需使用 /正则表达式字面量/ 创建一个正则表达式,并使用 =~ 运算符将其与你的字符串匹配。
- 在大多数面向对象语言中,在多个类之间共享代码的唯一方法是继承,并且你只能从单个类继承。如果一个对象需要来自多个其他类的行为,你必须要么使用其他几个对象组合该对象,要么在对象的类中复制来自这些其他类的方法。但是,在 Ruby 中,你有 混入 (mixins),它可以让你将来自几个不同 模块 (modules) 的方法混入到一个类中。(混入是方法的集合,就像一个类,只是你不能创建它的实例。)这提供了多重继承的所有好处(就像在 C++ 中一样),但没有增加复杂性。
- 在其他语言中,模拟对象以进行单元测试需要要么专门创建一个子类以在测试中使用,要么使用第三方 模拟 框架。在 Ruby 中,你可以简单地 直接在对象上重新定义方法。
我可以继续说下去,但我认为你明白了我的意思。Ruby 的创建者付出了很多努力,使该语言的几乎每个方面都简单而简洁。用 Ruby 编码更加愉快和高效。
不要误会我的意思,其他语言的严谨性可能有其好处。以类型检查为例:当然,必须声明每个变量和方法的类很麻烦。但是,与 Ruby 相比,进行类型检查的语言可以在编译时发现代码中更多的错误。静态类型化还允许编译器优化,从而使完成的应用程序运行更快。
但在实践中,我发现用 Ruby 编码的好处远远超过了成本。拥有一个可靠的单元测试套件(Ruby 使其易于编写)往往会捕获类型检查会捕获的所有相同错误。并且 Ruby 的灵活性使代码易于重构和维护。
如果你的开发时间对你来说很宝贵,并且你想最大限度地利用这段时间完成工作,那么你应该尝试一下 Ruby。但请注意:一旦你切换过来,你可能再也不想回去了!
4 条评论