tl;dr; Kernel#enum_for lets you treat your method like a collection.
I was iterating over the files in a folder, looking for those with a specific file extension. I had something like this...
Now I'm sure Ruby provides a better way to achieve this, but it worked for me... until I found I was filtering this list again in the block I was passing in.
What I wanted was something like this:
Well as per usual Ruby 2.0 has already thought of that.
Note the
Also.. I think this means I can also make it lazy like this...
Nice!
Update:
On a similar theme I was wrapping up a COM API that has iterators using
def for_all_files(f, e, &block) Dir[f+"/*"].each { |file| if(File.directory?(file)) for_all_files(file, e, &block) else block.call(file) if file.end_with?(e) end } end
Now I'm sure Ruby provides a better way to achieve this, but it worked for me... until I found I was filtering this list again in the block I was passing in.
for_all_files(source_folder, ".ts") do |file| if(path_filter =~ file) ... end end
What I wanted was something like this:
files(source_folder, ".ts"). select{|file| path_filter =~ file}.each do |file| ... end
Well as per usual Ruby 2.0 has already thought of that.
def files(folder, ending) def for_all_files(f, e, &block) Dir[f+"/*"].each { |file| if(File.directory?(file)) for_all_files(file, e, &block) else block.call(file) if file.end_with?(e) end } end enum_for(:for_all_files, folder, ending) end
Note the
enum_for
. It takes a symbol for a method name and a set of arguments. It returns an Enumerable that encapsulates your method. I really like the result of this but I don't like the code. If you know a better way, let me know. Post a comment telling me how I should have written it.Also.. I think this means I can also make it lazy like this...
files(source_folder, ".ts"). lazy. select{|file| path_filter =~ file}. each do |file| ... end
Nice!
Update:
On a similar theme I was wrapping up a COM API that has iterators using
Count
and Child(x)
methods. With Enumerator.new
you can easily wrap these to expose a clean ruby API.
def child_folders(folder) Enumerator.new do |y| (1..folder.Count).each {|i| y << folder.Child(i)} end end
No comments:
Post a Comment