Онзи ден трябваше да кача файлове на ftp сървър, нищо интересно. Проблема е че са ми много досадни повечетo FTP клиенти за Windows, просто една свястна FTP програма няма.
Днес имах малко свободно време и реших да направя нещо, което от доста време си мисля. А то е просто скиптче което само да го стартирам и то да си качи каквото трябва на избрано от мен място на ftp сървър (после мисля да го направя да прави и други работи, но за друг път)
Избрах си да го напиша на Ruby или по-точно JRuby, защото така и така го имах инсталирано и все се чудех за какво да го ползвам. Оказа че Ruby има наистина богат набор от стандартни класове. Поне за сега възползвах от Logger и Net::FTP.
Много харесвам Ruby като език, особено block-овете
Но е малко по различен от това с което съм работи до сега, например с PHP да направя нещо да обикаля директория и нейните под-директори е просто нещо такова:
function read_dir($directory){
foreach(new DirectoryIterator($directory) as $file){
if ($file == '.' || $file == '..') continue;
if ($file->isDir()){
read_dir($file->getRealPath());
// do something with directory
} else{
// do something with file
}
}
}
read_dir('my_dir');
или ползвам RecursiveDirectoryIterator, за който все забравям че съществува.
Пробвах да напиша нещо на същия принцип с ruby, но не стана много добре, даже никак добре не стана. Работеше, но бях се по оплел със функции, Proc
Порових малко в net-a и с малко работа написах това:
def read_dir (path, &block)
paths = [path]
while file = paths.shift
yield file.dup
next unless File.directory? file
for f in Dir.open( file )
next if f == '.' or f == '..'
paths.unshift File.join(file, f)
end
end
end
read_dir('my_dir') do |file|
# do something with file
end
Винаги съм мислил, че за да се обиколи директория и нейните под-директории трябва някаква рекурсия или нещо такова. А се по този начин просто се пазят всичките директории в масив(или опашка) и просто се обикаля докато се свърши масива.
Обаче се оказа че в Ruby вече има такова нещо - Find:
require 'find'
Find.find('my_dir') do |file|
# do something with file
end
Е малко това Find.find() не ми харесва как изглежда, но само със едно “alias :find :from”, може да имаме Find.from() което да е същото
А ако сте фенове на Monkey patch може да се вложи Find.find във File класа и да се направят още доста “магии”.

