2011-05-02 69 views
0

我想在深入rails開發之前深入學習ruby,但是我有一些學習類的問題。我似乎無法理解爲什麼以下不起作用。Ruby初學者課題

#point.rb 
class Point 
    attr_accessor :x, :y 

    def initialize(p = [0,0]) 
    @x = p[0] 
    @y = p[1] 
    end 
end 

#shape.rb 
require_relative 'point.rb' 

class Shape 

    attr_accessor :points 

    def initialize *the_points 
    for p in the_points 
     @points.append Point.new(p) 
    end 
    end 

end 

s = Shape.new([3,2]) 

puts s.points 

當我調用該函數時,我得到一個NilClass的無方法錯誤,我假設它指的是@point.append。

回答

5

首先,試試這個:

def initialize *the_points 
    @points = [] 
    for p in the_points 
    @points << Point.new(p) 
    end 
end 

你得到NilClass錯誤,因爲@points實例變量是零,而NilClass,不具有append()方法。

+0

現在我發現了一個不同的錯誤:'shape.rb:11:在塊在初始化:未定義的方法 '追加' 的[]:陣列(NoMethodError)' 這對我來說真的很讓人困惑,因爲我認爲這個數組在追加時會很好。如果這很重要的話,我正在使用紅寶石1.9.2。 – tshauck 2011-05-02 17:31:38

+1

@tshauck - 你可以使用'push'或'<<'來替代,Array上沒有'append'方法。 – McStretch 2011-05-02 17:33:35

+0

嗯......這有點令人驚訝,但我沒有看到Array#追加到Ruby 1.9.2中。您應該使用<<(例如,@points << Point.new(p)) – rmk 2011-05-02 17:37:06

0

您需要將@points初始化爲新數組。它始於零。

def initialize *the_points 
    @points = []; 
    for p in the_points 
     @points.append Point.new(p) 
    end 
    end 
1
比創建一個數組,並在循環中填充它更好

將初始化它像這樣:

class Shape 
    attr_accessor :points 

    def initialize *the_points 
    @points = the_points.map{ |p| Point.new(p) } 
    end 
end 
+1

無點式FTW:'the_points.map(&Point.method(:new))'。其實,我有這樣的想法,即類是程序,即它們是產生實例的程序。就像任何Ruby中的過程對象一樣,它們應該實現'to_proc',這樣就可以編寫'the_points.map(&Point)'。猴子補丁很簡單:class Class; def to_proc; proc(&method(:new))end end'。 – 2011-05-03 03:35:37

+0

@Jörg我希望你得到評論upvotes的代表,因爲這是你在這裏分享的一些瘋狂的好想法。 :) – Phrogz 2011-05-03 03:51:24

+0

我想我發佈的地方。至少我只是在我的StackOverflow片段目錄中找到它,但也許它是爲了我給出的答案,但從未公佈過。 – 2011-05-03 03:57:02

1

如果您對(ruby -w$VERBOSE = true)警告,它會提醒你, @points不存在。

查看其它一些調試提示在How do I debug Ruby scripts?