技术开发 频道

没有Rails Java程序员如何使用Ruby


八、RubyBeans?

你可能已经从列表3的两个加粗的类中注意到,Ruby支持使用速记符号来定义属性:它们是attr_reader和attr_writer。因为我使用了这种符号,所以我可以set和get在我的Word类中的相应的属性,见列表7:

列表7.使用attr_reader和attr_writer

            

require "dictionary"

wrd = Dictionary::Word.new("turpitude", "Noun")

wrd.part_of_speech # "Noun"

wrd.spelling # "turpitude"

wrd.spelling = "bibulous"

wrd.spelling # "bibulous"

syns = [Dictionary::Word.new("absorptive", "Adjective"),

Dictionary::Word.new("imbibing", "Noun") ]

#危险!

wrd.synonyms = syns = syns #出现错误提示-"Exception: undefined method `synonyms='..."

attr_reader和attr_writer都不是关键字,而实际上都是Ruby中的方法(可以在Module类中找到它们)-它们使用符号作参数。一个符号是以冒号(:)开头的任何变量,甚至在有些情况下,符号本身就是对象!

注意,因为我在列表3中使synonyms成为只读的,所以Ruby否定了我在列表7中最后一行代码的尝试。

另外,我可以使用attr_accessor方法编写属性声明代码以指出一个属性既可读也可写。

九、迭代

灵活的迭代是Ruby编程的快乐之一。请参考列表8,其中列出的是Word的initialize()方法的代码:

列表8.Closures非常方便

            

def initialize(spelling, part_of_speech, definitions = [], synonyms = [])

@spelling = spelling

@part_of_speech = part_of_speech

definitions.each{ |idef| idef.word = self}

@definitions = definitions

@synonyms = synonyms

end 

列表8中的第四行代码中出现了一些不同的东西。对于入门者来说,当我调用definitions实例上的每个方法时,我使用了大括号。每个方法实质上类似Java语言中的一个Iterator,但是它更简单。在列表8中,由每个方法处理迭代细节而只需调用者专注于期望的效果。在此例中,我传递了一个块,其意思是“for each value in the collection”,也就是idef,它是Definition的一个实例。

列表9实质上展示了用Java语言实现的同一行代码(来自于Word的构造器中,见列表1):

列表9.前面Ruby的每个方法都类似Java的迭代算子

            

for(Iterator iter = definitions.iterator(); iter.hasNext();){

this.validateRelationship((Definition)iter.next());

}

现在,我要承认Java 5的针对于for循环语法的泛型和new比列表9中要简洁得多。Ruby支持我们熟悉的Java中的循环结构,如for和while;实际上,在Ruby中,它们是很少使用的,因为在Ruby中的大多数东西都支持迭代的概念。例如,在列表10中,你会看到实现对于一个文件内容的迭代是多么容易:

列表10.迭代变得非常简单

            

count = 0

File.open("./src/dictionary.rb").each { |loc| puts "#{count += 1}:" + loc }

Ruby中的支持each方法的任何类(如File)都可以让你用这样方式进行迭代。顺便说一下,Ruby的puts方法(见列表10)与Java语言中的System.out.println一样。

十、条件语句

现在,让我们仔细地分析一下在列表3中的Word类中的一个条件语句。在列表11中,我列出了add_definition()方法的代码:

列表11.巧妙的条件表达

            

def add_definition(definition)

definition.word = self if definition.word != self

@definitions << definition

end

请仔细观察在第二行中的代码,看一下if语句是怎样跟随表达式的。你当然可以以正常方式书写它(由列表12所示),但是是否列表11更好些?

列表12.使用多种方式来表达一个条件

            

def add_definition(definition)

if definition.word != self

definition.word = self

end

@definitions << definition

end

在Java语言中,如果条件语句体只占一行,那么你可以删除大括号。在Ruby中,如果条件语句体只占一行,那么你可以编写象列表11所示的表达式。还要注意,同一样的条件也可以表达为"definition.word = self unless definition.word == self",在此使用了Ruby的"unless"特征。效果如何?


0
相关文章