2015-01-07 41 views
0

在红宝石对象内导航非常简单。考虑下面的伪代码,并利用这一段为例输入,下面的调用有意义,工作原理:导航Ruby对象

forth_word = Par.sentence[0].word[3] 
puts forth_word.text #"ruby" 
puts forth_word.type #:noun 

伪包含在每个其他中类代码:(排序的嵌套,但不是严格OOP意义)

class Paragraph 
    @page_number = #1 (default) 
    @sentences = [] 
end 

class Sentence 
    @is_a_quote = #false (default) 
    @words = [] 
end 

class Word 
    @text =# "ruby" 
    @type =# :noun 

    def in_a_quote? 
    #... return [email protected]_a_quote 
    end 

    def on_page 
    #... return Paragraph.Sentence.page 
    end 
end 

,当我尝试向上导航Ruby对象树...又名询问从里面的Word属于句子或段落对象的信息最棘手的部分就越大。任何建议,我怎么能代码的最后2种方法:

puts forth_word.in_a_quote #false 
puts forth_word.on_page  #1 
+1

这种类型的数据结构不适合您的要求。将数据存储在sql中,并使用ORM按照您的设想检索数据。 –

+3

请将“sudo”更改为“pseudo”。这让我疯狂。而且,对于'Sentence'和'Word'来嵌套,你需要定义它们'class Sentence

+0

@CarySwoveland:Omigod,你是个天才。我试图弄清楚这与超级用户权限有什么关系......但是,在你的下一个评论中你错了:OP不是按层次结构(is-a)嵌套,而是通过遏制(has- a,在实例变量中),这是正确的做法:“Word”当然不是“Sentence”类型,也不是“Paragraph”类型的“Sentence”。 – Amadan

回答

2

每一个字可以有指向句子是在一个句子中的变量相同的句子和中─和段落和页面。

+0

谢谢!这似乎是直截了当的解决方案(我不知道为什么我没有想到它),我唯一的反对意见是它似乎不是非常干燥。对于我创建的每个班级,我都记得把一个占位符放到'父'班。也许这只是OOP设计的可能解决方案,但我认为可能有本地方法。这看起来类似于浏览网页DOM树或XML文档。不确定这些解析器是否像你描述的那样使用指针或其他魔法。 – Nathan

+0

默认情况下,Ruby变量是通过引用传递的,所以它很可能是一个指针(尽管我不太确定)。我相信我的解决方案是干的,因为没有重复的代码。 – Dbz

0

首先,你的类不是嵌套的。他们应该在对方内部宣布。

class Paragraph 
    @page_number = #1 (default) 
    @sentences = [] 

    class Sentence 
     @is_a_quote = #false (default) 
     @words = [] 

     class Word 
      @text =# "ruby" 
      @type =# :noun 
     end 
    end 
end 

但与Ruby中的Java不同,您不能从内部访问外部类的变量。 Ruby Constants and Nested Classes 最好使用模块而不是嵌套类。

但是,如果您仍想使用与您的示例中相同的层次结构,请注意访问班级以外的数据。 例如,你如果试图执行这段代码

class Word 
    @text =# "ruby" 
    @type =# :noun 

    def in_a_quote? 
    #... return [email protected]_a_quote 
    end 
end 

w = Word.new 
w.is_a_quote? 

这是非常危险的,对矛盾OOP原则得到一个错误。

+0

我同意'嵌套'不是合适的术语,但不知道如何描述它。你能解释为什么这是危险的,它会违反什么原则? – Nathan

+0

这很危险,因为Word.is_a_quote方法依赖于假设,然后有一些Sentence类的对象,它有一个参数@is_a_quote。但是,如果我们从Sentence类中删除@is_a_quote,或者只是尝试执行我在我的答案中编写的一段代码,该方法会返回什么结果?封装完全违反。如果你想要一个方法'is_a_quote?你必须在最合乎逻辑的地方在Sentence类中声明它。 –