J
Jay McGavren
I'm going to be re-using this technique at quite a few places in my
code, so I want to be certain I have it right...
I started with code like this, within a method:
for playlist in playlists
with_option_values('find', config) do |terms|
if (results = playlist.Search(terms, 0))
results.each {|track| tracks.push(track)}
end
end
with_option_values('visible-find', config) do |terms|
if (results = playlist.Search(terms, 1))
results.each {|track| tracks.push(track)}
end
end
#Repeat several more times...
end
I of course hate repeating myself like that. I don't want to create a
super-specialized instance or class method, though. So I tried a
nested method:
for playlist in playlists
def search_playlist(playlist, option, config, field_id, tracks)
with_option_values(option, config) do |terms|
if (results = playlist.Search(terms, field_id))
results.each {|track| tracks.push(track)}
end
end
end
search_playlist(playlist, 'find', config, 0, tracks)
search_playlist(playlist, 'visible-find', config, 1, tracks)
#Repeat several more times...
end
....I wanted to do search_playlist(option, field_id), but I had to add
parameters for the playlist, config, and tracks as well, because they
fall out of scope when the method is called. Yuck!
So finally, I went with a Proc, because I know a block/Proc stores all
variables that are in scope when it's defined:
for playlist in playlists
search_playlist = lambda {|option, field_id|
with_option_values(option, config) do |terms|
if (results = playlist.Search(terms, field_id))
results.each {|track| tracks.push(track)}
end
end
}
search_playlist.call('find', 0)
search_playlist.call('visible-find', 1)
#Repeat several more times, with a lot less typing.
end
search_playlist falls out of scope when the enclosing method ends, so
I think I'm safe from playlist, tracks, etc. living forever on the
stack, right? Also, how bad is it that I'm creating the Proc inside a
(not very tight) loop?
code, so I want to be certain I have it right...
I started with code like this, within a method:
for playlist in playlists
with_option_values('find', config) do |terms|
if (results = playlist.Search(terms, 0))
results.each {|track| tracks.push(track)}
end
end
with_option_values('visible-find', config) do |terms|
if (results = playlist.Search(terms, 1))
results.each {|track| tracks.push(track)}
end
end
#Repeat several more times...
end
I of course hate repeating myself like that. I don't want to create a
super-specialized instance or class method, though. So I tried a
nested method:
for playlist in playlists
def search_playlist(playlist, option, config, field_id, tracks)
with_option_values(option, config) do |terms|
if (results = playlist.Search(terms, field_id))
results.each {|track| tracks.push(track)}
end
end
end
search_playlist(playlist, 'find', config, 0, tracks)
search_playlist(playlist, 'visible-find', config, 1, tracks)
#Repeat several more times...
end
....I wanted to do search_playlist(option, field_id), but I had to add
parameters for the playlist, config, and tracks as well, because they
fall out of scope when the method is called. Yuck!
So finally, I went with a Proc, because I know a block/Proc stores all
variables that are in scope when it's defined:
for playlist in playlists
search_playlist = lambda {|option, field_id|
with_option_values(option, config) do |terms|
if (results = playlist.Search(terms, field_id))
results.each {|track| tracks.push(track)}
end
end
}
search_playlist.call('find', 0)
search_playlist.call('visible-find', 1)
#Repeat several more times, with a lot less typing.
end
search_playlist falls out of scope when the enclosing method ends, so
I think I'm safe from playlist, tracks, etc. living forever on the
stack, right? Also, how bad is it that I'm creating the Proc inside a
(not very tight) loop?