2011-09-29 26 views
1

我完全沉迷於這一個。無法賦值給變量:未定義的方法`[]'爲零:NilClass(NoMethodError)

我有以下代碼:

puts block.at_xpath("*/img")["width"].to_i 

但是當我將其更改爲

width = block.at_xpath("*/img")["width"].to_i 

我得到這個錯誤:當我有看跌期權在那裏

NokogiriTUT.rb:70:in `blockProcessor': undefined method `[]' for nil:NilClass (NoMethodError) 

它返回預期值。

更新:

 def blockProcessor(block) 
    header = block.xpath('td[@class="default"]/*/span[@class="comhead"]') 
    array = header.text.split 
    if array[0] != nil #checks to make sure we aren't at the top of the parent list 
     ### Date and Time ### 
     if array[2] == 'hours' || array[2] == 'minutes' 
      date = Time.now 
     else 
      days = (array[1].to_i * 24 * 60 * 60) 
      date = Time.now - days 
     end 

     ##Get Comment## 
     comment = block.at_xpath('*/span[@class="comment"]') 

     hash = comment.text.hash 
     #puts hash 

     ##Manage Parent Here## 

      width = block.at_xpath("*/img")["width"].to_i 



      prevlevel = @parent_array[@parent_array.length-1][1] 
      if width == 0 #has parents 
       parentURL = header.xpath('a[@href][3]').to_s 
       parentURL = parentURL[17..23] 
       parentURL = "http://news.ycombinator.com/item?id=#{parentURL}" 
       parentdoc = Nokogiri::HTML(open(parentURL)) 
       a = parentdoc.at_xpath("//html/body/center/table/tr[3]/td/table/tr") 
       nodeparent = blockProcessor(a) 
       @parent_array = [] 
       node = [hash, width, nodeparent] #id, level, parent 
       @parent_array.push node  
      elsif width > prevlevel 
       nodeparent = @parent_array[@parent_array.length-1][0] 
       node = [hash, width, nodeparent] 
       @parent_array.push node 
      elsif width == prevlevel 
       nodeparent = @parent_array[@parent_array.length-1][2] 
       node = [hash, width, nodeparent] 
       @parent_array.push node 
      elsif width < prevlevel 
       until prevlevel == w do 
        @parent_array.pop 
        prevlevel = @parent_array[@parent_array.length-1][1] 
       end 
       nodeparent = @parent_array[@parent_array.length-1][2] 
       node = [hash, width, nodeparent] 
       @parent_array.push node 
      end 
     puts "Author: #{array[0]} with hash #{hash} with parent: #{nodeparent}" 

     ##Handles Any Parents of Existing Comments ## 
     return hash 
    end 
end 
    end 

這裏是它作用於塊。

<tr> 
    <td><img src="http://ycombinator.com/images/s.gif" height="1" width="0"></td> 
    <td valign="top"><center> 
    <a id="up_3004849" href="vote?for=3004849&amp;dir=up&amp;whence=%2f%78%3f%66%6e%69%64%3d%34%6b%56%68%71%6f%52%4d%38%44"><img src="http://ycombinator.com/images/grayarrow.gif" border="0" vspace="3" hspace="2"></a><span id="down_3004849"></span> 
    </center></td> 
    <td class="default"> 
    <div style="margin-top:2px; margin-bottom:-10px; "><span class="comhead"><a href="user?id=patio11">patio11</a> 12 days ago | <a href="item?id=3004849">link</a> | <a href="item?id=3004793">parent</a> | on: <a href="item?id=3004471">Ask HN: What % of your job interviewees pass FizzB...</a></span></div> 
    <br><span class="comment"><font color="#000000">Every time FizzBuzz problems come up among engineers, people race to solve them and post their answers, then compete to see who can write increasingly more nifty answers for a question which does not seek niftiness at all.<p>I'm all for intellectual gamesmanship, but these are our professional equivalent of a doctor being asked to identify the difference between blood and water. You can do it. <i>We know</i>. Demonstrating that you can do it is not the point of the exercise. We do it to have a cheap-to-administer test to exclude people-who-cannot-actually-program-despite-previous-job-titles from the expensive portions of the hiring process.</p></font></span><p><font size="1"><u><a href="reply?id=3004849&amp;whence=%2f%78%3f%66%6e%69%64%3d%34%6b%56%68%71%6f%52%4d%38%44">reply</a></u></font></p> 
    </td> 
</tr> 
+0

您是否在調用'at_xpath'之前嘗試添加'puts block'。也許你有一個副作用,正在改變'塊' – knut

+0

@ knut,我只是再檢查一下,那是有效的。另外,投入給我我期望和想要的價值是奇怪的。我想要做的就是將它分配給一個變量。 –

+0

「width = ...」賦值和「Factory」是什麼? –

回答

3

您的基本問題是您不瞭解XPath。 (你在那裏很好,XPath很混亂。)你的選擇器根本不符合你認爲的匹配。特別是,一個炸燬

*/img 

應該

//img 

或類似的東西。現在

因爲中的XPath選擇不匹配什麼,這個Ruby代碼

block.at_xpath("*/img") 

爲零的值。並且nil不支持[],所以當您嘗試打電話給["width"]時,Ruby抱怨出現undefined method [] for nil:NilClass錯誤。

至於爲什麼只有當你把它分配給一個變量時纔會爆炸......是的,這並不是實際發生的事情。你也可能改變了其他的東西。


現在,請允許我做一些其他的希望建設性的批評代碼:

  • 你的問題顯然是爲了讓人很難回答的問題。將來,請隔離代碼,不要粘貼你的整個家庭作業(或任何此屏幕刮板)。

  • 這將是額外的巨大的,如果你把它做成了一個可運行的Ruby文件,我們可以在我們的計算機逐字執行,例如:

require "nokogiri" 
doc = Nokogiri.parse <<-HTML 
<tr> 
    <td><img src="http://ycombinator.com/images/s.gif" height="1" width="0"></td> 
    <td valign="top"><center> 
    <a id="up_3004849" href="vote?for=3004849&amp;dir=up&amp;whence=%2f%78%3f%66%6e%69%64%3d%34%6b%56%68%71%6f%52%4d%38%44"><img src="http://ycombinator.com/images/grayarrow.gif" border="0" vspace="3" hspace="2"></a><span id="down_3004849"></span> 
    </center></td> 
    <td class="default"> 
    <div style="margin-top:2px; margin-bottom:-10px; "> 
     <span class="comhead"> 
     <a href="user?id=patio11">patio11</a> 12 days ago | <a href="item?id=3004849">link</a> | <a href="item?id=3004793">parent</a> | on: <a href="item?id=3004471">Ask HN: What % of your job interviewees pass FizzB...</a> 
     </span> 
    </div> 
    <br><span class="comment"><font color="#000000">Every time FizzBuzz problems come up among engineers, people race to solve them and post their answers, then compete to see who can write increasingly more nifty answers for a question which does not seek niftiness at all.<p>I'm all for intellectual gamesmanship, but these are our professional equivalent of a doctor being asked to identify the difference between blood and water. You can do it. <i>We know</i>. Demonstrating that you can do it is not the point of the exercise. We do it to have a cheap-to-administer test to exclude people-who-cannot-actually-program-despite-previous-job-titles from the expensive portions of the hiring process.</p></font></span><p><font size="1"><u><a href="reply?id=3004849&amp;whence=%2f%78%3f%66%6e%69%64%3d%34%6b%56%68%71%6f%52%4d%38%44">reply</a></u></font></p> 
    </td> 
</tr> 
HTML 

width = doc.at_xpath("*/img")["width"].to_i 

這樣我們可以用我們的電腦進行調試,而不僅僅是用我們的思想。

  • 你寫Ruby現在,而不是Java,所以符合Ruby的spacing and naming conventions:文件名snake_case,縮進2個空格,沒有標籤,等等。這真的是很難讀取按照以下格式錯誤的代碼 - 「錯」是指「非標準」。

  • 無處不在你有一個描述性評論(### Date and Time ###)是一個機會提取方法(def date_and_time(array)),並使您的代碼更清潔,更容易調試。

+0

感謝您花時間提供這麼多的細節。我非常欣賞讓我成爲更好的程序員的觀點。包含可運行代碼是一個絕妙的想法,我敢打賭90%的人不這麼做。另外,您正確地指定變量不是問題。我可以通過取消註釋並推薦行「nodeparent = blockProcessor(a)」來使錯誤出現並消失 –

相關問題