Closed kazuminn closed 9 years ago
えーっと。ちょっと整理したいのだけれど 配列に nil が入ることがあるので compact したい、ってのはokです。
compact!メソッドをeachの前に入れても、破壊されたものがNillclassのものなので
ってのが良く分からないです。 どういう風に実行した時に何が起きて何がダメかちょっとまとめてみましょう (あと、このコードそのままじゃ動かない気もします……)
あとエスパーすると nil な時にまずいのは x.in_reply_to_screen_name
な気がする。
こんな感じ?
client = Twitter::REST::Client.new do |config|
config.consumer_key = "fQDpM4Hf9W3c6n3X5heJwLZ74"
config.consumer_secret = "wlx82Y2zLx0PvAnW6OTjVNBWa2uJjlwysHgCa70iFq8NG0MSNx"
config.access_token = "2416079641-KZuLIT277rtE1EoNQoq6HcC65wcyAMGkt7f4QOe"
config.access_token_secret = "BG4FSx2iXMztvwYQ8GAm9j2qfSBtHQBAfVFcYOl0cfB3V"
end
hash = {}
client.user_timeline("warugaki_kazumi").each do |x|
screen_name = x.in_reply_to_screen_name
unless screen_name.nil?
unless hash.has_key?(screen_name) then
hash[x.in_reply_to_screen_name] = 1
else
hash[x.in_reply_to_screen_name] = 2
end
end
end
hash.each do |key,value|
if value.to_i == 1
client.update("@warugaki_kazumiは、" + key + "さんにクソリプをしている可能性があります。")
end
end
あと細かいところ
hash = {}
だと何のハッシュだか分からない)@atton- consumer_secret
とaccess_token_secret
ベタ書きで貼るのは不味いのでは
エスパーすると
client.user_timeline("warugaki_kazumi") # => nil
のときにeach
を呼ぶと
client.user_timeline("warugaki_kazumi").each do # nil.eachしてるのでエラー
みたいな感じですか?
@atton- さん @hanachin さん tokenの件は、regenerateしたので大丈夫です。
事の発端は、
client.user_timeline("warugaki_kazumi").each do
だと、 x.in_reply_to_screen_nameがxがnilの時エラー
で、nilを消そうとcompact!
client.user_timeline("warugaki_kazumi").compact!.each do
ってすると、compact!によって破壊されたものはNilクラスのインスタンスなので、 eachメソッドを使うとエラーがでるよー。で
破壊しないようにcompact
client.user_timeline("warugaki_kazumi").compact.each do
だが、
kusoripu.rb:15:in `block in <main>': can't convert Twitter::NullObject to Integer (Twitter::NullObject#to_int gives Twitter::NullObject) (TypeError)
と激おこ。
nil消したはずなのに「あれー?」って感じですね。
細かいことを付け足すと
client.user_timeline("warugaki_kazumi").each do # nil.eachしてるのでエラー
ってのは、厳密にはnill.eachしてないので、エラーにならないのでは。
client.user_timeline("warugaki_kazumi").compact!.class #Nillクラス
これ、compact!で破壊されたものはNillクラスのインスタンスなんですね。
compact
とcompact!
は動作が違いますね。compact!
で何も変更がなかった場合nil
が返ります
compact は自身から nil を取り除いた配列を生成して返します。 compact! は自身から破壊的に nil を取り除き、変更が 行われた場合は self を、そうでなければ nil を返します。 http://docs.ruby-lang.org/ja/2.2.0/method/Array/i/compact.html
@hanachin さん なるほどです。 compactを使えばいいのですね。
でも
kusoripu.rb:15:in `block in <main>': can't convert Twitter::NullObject to Integer (Twitter::NullObject#to_int gives Twitter::NullObject) (TypeError
と怒られます。
compact は client.user_timeline("warugaki_kazumi")
の中身に nil がある時に消します。
今回 nil なのは client.user_timeline("warugaki_kazumi")
の中身の tweet の in_reply_to_screen_name
なので、 each に失敗してるんじゃなくて hash への代入に失敗してますね
https://gist.github.com/atton-/ea9178765cf4fcdfcc83
https://twitter.com/_atton/status/578177683873349632
hash で返るものには to_int が必要
ってhash methodの戻り値のオブジェクトにはto_intなinstance methodを持っていなければならない って解釈でいいです?
ってhash methodの戻り値のオブジェクトにはto_intなinstance methodを持っていなければならない って解釈でいいです?
その解釈であってます。 ちなみにこれが原因でどのようなことが起こってるか説明できます?
to_int methodを持っていないから、hashインスタンスのkeyにできない事案が起こっている。
ですかね?
だいたいあってます。 key にしようとして to_int が存在していないものは何です?
HasHashMethod.new オブジェクトですよね。
あーっと。私の gist じゃなくて君のコードの方ね。
あ。x.in_reply_to_screen_nameの戻り値。ですかね。
そうそう正解。
だから、
kusoripu.rb:15:in `block in
': can't convert Twitter::NullObject to Integer (Twitter::NullObject#to_int gives Twitter::NullObject) (TypeError
のエラーは each とか compact が問題ではなくて、 x.in_reply_to_screen_name
の object を hash の key にしてるのが問題、というお話でした
あ、なるほどです。
hashではなくて他のものにすれば、動きそうですね。
よくわかりました。ありがとうございました。
ruby 2.1.5 mac ox 10.10
https://github.com/kazuminn/twitter_/blob/master/kusoripu.rb (コンセプトはreadme見てください。) こちらのコード16行目の配列でnilが入ってると、その先の n_reply_to_screen_nameメソッドはレシーバーがnilだとエラーが起きちゃうわけです。 compact!メソッドをeachの前に入れても、破壊されたものがNillclassのものなので eachはダメだと怒られちゃいます。
どうすればよいでしょうか。