2012-11-22 57 views
0

我寫了一個模型中的一個函數到一個單獨的模型中刮網站和存儲的某些屬性(story):陣列範圍內被認可爲字符串 - 不能轉換成整數

def get_content 

      request = HTTParty.get("#{url}") 

      doc = Nokogiri::HTML(request.body) 

     doc.css("#{anchor}")["#{range}"].each do |entry| 

      story = self.stories.new 
      story.title = entry.text 
      story.url = entry[:href] 
      story.save 

     end 

這將使用url,anchorrange Sections變量的屬性。範圍屬性存儲爲數組範圍 - 即0..211..13 - 但是,我被告知無法將字符串轉換爲變量。我試圖將range作爲整數和字符串存儲,但都失敗。

我意識到我可以輸入範圍的開始和結束作爲兩個單獨的整數在我的分貝,並把["#{beginrange}".."#{endrange}"],但這似乎是一個混亂的方式做到這一點。

還有其他想法嗎?提前

回答

1

嗯非常感謝,如果你是確保range總是喜歡一個字符串「1..2」(「<Integer >..<Integer>」),可以使用eval方法:

在我的IRB控制檯:

1.9.3p0 :032 > (eval "1..2").each { |l| puts l } 
1 
2 
=> 1..2 
1.9.3p0 :033 > (eval "1..2").inspect 
=> "1..2" 
1.9.3p0 :034 > (eval "1..2").class 
=> Range 

你的情況:

doc.css("#{anchor}")[eval(range)].each do |entry| 
    #... 
end 

eval是一種危險。如果您確定range屬性是以字符串形式顯示的範圍(驗證和正則表達式可以幫助您),則可以使用eval,而沒有風險。

+0

不勝感激,謝謝! –

+0

不客氣;) – MrYoshiji

+0

這實際上解決了我的問題,它現在正在工作!範圍始終是一個字符串,因爲我將它個人輸入到數據庫中。再次感謝! –

0

有幾件事我看錯了。

["#{beginrange}".."#{endrange}"]創造了一系列的字符,而不是一個整數範圍,其中Array[]需求:

beginrange = 1 
endrange = 2 

["#{beginrange}".."#{endrange}"] 
=> ["1".."2"] 

[beginrange..endrange] 
=> [1..2] 

但是,你存儲你需要一個字符串數組範圍的代表性。如果我有一個範圍的字符串表示,我會使用這樣的:

range_value = '1..2' 

[Range.new(*range_value.scan(/\d+/).map(&:to_i))] 
=> [1..2] 

或者,如果有我會遇到一個異範圍的機會:

[Range.new(*range_value.scan(/\d+/).map(&:to_i), range_value['...'])] 
=> [1..2] 

range_value = '1...2' 

[Range.new(*range_value.scan(/\d+/).map(&:to_i), range_value['...'])] 
=> [1...2] 

這些都是好的當你不能相信你的Range字符串表示的源代碼時,也就是說,這個值來自別人創建的表單或文件。如果你擁有傳入的值,或者,爲了方便,將其存儲在數據庫中的字符串,可以使用eval輕鬆地重新創建範圍:

eval('1..2').class 
=> Range 
eval('1..2') 
=> 1..2 
eval('1...2') 
=> 1...2 

人都害怕eval,因爲,不明智地使用,它是危險的。這並不意味着我們應該避免使用它,相反,我們應該在安全時使用它。

你可以使用正則表達式來檢查字符串的格式,拋出一個異常,如果它是不能接受的,然後繼續:

raise "Invalid range value received" if (!range_value[/\A\d+\s*\.{2,3}\s*\d+\z/]) 
[eval(range_value)] 
+0

真的很感激它,夥計,謝謝。 –