先日
MacRuby で iTunes から重複する曲を削除するものを作りました。
https://gist.github.com/1382271
(OS X 10.7.2 限定)
-- 参考にさせていただいたサイト
# ファイルを移動させる際の条件など大変参考になりましたし、
# MacRuby についての情報もいろいろありました。
iTunesに重複登録されている音楽ファイルを削除する - Watsonのメモ
# iTunes.app に下記のような機能があったことをこれまで知りませんでした。
iTunes ライブラリで重複した項目を検索し、削除する方法
-- 当初、最も悩んだこと
track.delete
を実行すると なぜか MacRuby がクラッシュしました。
MacRuby バージョンは
% macruby -v
MacRuby 0.11 (ruby 1.9.2) [universal-darwin11.0, x86_64]
重複する曲が 20 個以上あるとき
playlist.tracks の曲を each でまわし一定の条件を満たしたタイミングで
track.delete するとクラッシュしました。
こんな感じ。
myplaylist.tracks.each{|x|
if ...
# x がなにかの条件をみたしたら
x.delete
# この瞬間にクラーッシュ!
}
それで、オブジェクトを探ってみることに...
test.rb
framework "ScriptingBridge"
i = SBApplication.applicationWithBundleIdentifier("com.apple.iTunes")
a = i.sources[0].userPlaylists.find{|x| x.name == "ミュージック"}.tracks
p b = a[0]
p c = a[0]
p b.equal?(c)
#=>
% macruby test.rb
false
なんと false がかえってきました。
b, c は object としてはイコールでは『ない』とのこと。
a は1度しか定義していないにもかかわらず...。
例えば、Ruby 1.9 では
a = ["a","b","c"]
b = a[0]
c = a[0]
p b.equal?(c)
#=>
% ruby193 -v aaa.rb
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]
true
true がかえってきます。
MacRuby のこの件について理解できておりませんが、ともかく
この事が原因でクラッシュをひきおこしているのかも? と考え
一意の曲オブジェクトを「確実」に指名する方法をとることにしました。
要は
track.databaseID
を使うことにしました。
こんな感じです。
条件をみたした 曲オブジェクトの databaseID を hash に溜め込んでから、
hash を each でまわしつつ
その都度 fileTracks から 指定した databaseID に基づいて曲オブジェクトを検索し
検出できたら
.delete
を実行...
@h.each{|k,v|
t = @filetracks.find{|x| x.databaseID == k}
next unless t
t.delete
}
このようにしてみたところ .delete を実行しても
クラッシュしなくなりました。
# あくまでも私の環境下においてでは!です。
# ちなみに .fileTracks と .tracks の 2 種類ありますが
# 上記では .fileTracks を対象にしています。
0 件のコメント:
コメントを投稿