Ruby Blocks for better code reuse
While working on some disk space / folder structure scripts I had several functions which hierarchically search the disk then performed some custom function. When refactoring the code I realised that the specific functions could be contained in a block and passed to a generic search method.
This is one of the original functions
def search_folder( folder )
sub_folders = Dir.glob( folder + '*/')
sub_files = Dir.glob( folder + '*.*')
## Recursive
sub_folders.each do |sub_folder|
search_folder( sub_folder )
end
sub_files.each do | sub_file |
if sub_file.match(/\.rar$/)
puts sub_file
end
end
end
Refactored to take a block
def search_folder( folder, &block )
sub_folders = Dir.glob( folder + '*/')
sub_files = Dir.glob( folder + '*.*')
## Recursive
sub_folders.each do |sub_folder|
search_folder( sub_folder, &block )
end
sub_files.each do | sub_file |
yield(sub_file)
end
end
And where the original method was called replace with:
search_folder( folder ) do |file|
if file.match(/\.rar$/)
puts file
end
end
Encapsulate with Modules
Wrapping the generic methods up into a module and calling local methods from the block.
module GenericStuff
def self.search_folder( folder, &block )
sub_folders = Dir.glob( folder + '*/')
sub_files = Dir.glob( folder + '*.*')
## Recursive
sub_folders.each do |sub_folder|
search_folder( sub_folder, &block )
end
sub_files.each do | sub_file |
yield(sub_file)
end
end
end
def limit
@count ||= 1
puts "Count is " + @count.to_s
if @count > 2
exit( -1 )
end
@count += 1
end
# Call to generic method, block calls local method
folder = '/'
GenericStuff::search_folder( folder ) do |file|
if file.match(/\.rar$/)
limit
puts file
end
end
Programming
Ruby
]