понедельник, 21 января 2008 г.

Книжка по Ruby

Нашёл и скачал в интернете неплохую книгу по Ruby - Programming Ruby. The Pragmatic Programmer's by Guide. David Thomas Andrew Hunt. Это книга тех же авторов, что и книги под названием "Программист-прагматик. Путь от подмастерья к мастеру", которую я читал ранее. Несмотря на то, что эта книга на английском, читается достаточно легко, чтобы я не бросил это занятие =).
Книга состоит из четырёх основных частей.

  1. Facets of Ruby. В этой части рассмотрены основные особенности Ruby и его отличия от других языков.
  2. Ruby in Its Setting. Здесь рассмотрено каким образом Ruby взаимодействует со своим окружением.
  3. Ruby Crystallized. Эта часть содержит в себе более продвинутый материал, относящийся к "сложным" частям языка.
  4. Ruby Library Reference. Описание встроенных классов и функций языка.

четверг, 17 января 2008 г.

Реальное применение

Вчера на работе понадобилось преобразовать файл из SVG-формата, в наш собственный. И для этого я решил написать скрипт. Вначале попробовал это сделать на Tcl, но у него таки несколько грамоздкий синтаксис, когда нужно заниматься поиском подстрок и тому подобными вещами(допускаю, что я просто недостаточно хорошо разобрался). Поэтому я использовал Ruby. Здесь проблем вообще не возникло. Я использовал то, что уже делал раньше и всё легко получилось. Так что похоже это и есть первый случай реального применения мной Ruby.

вторник, 15 января 2008 г.

Странная находка

Неожиданно обнаружил, что в составе Ruby присутствует библиотека tcltk, позволяющая использовать интерпритатор Tcl в Ruby-программе. Никак не могу придумать зачем это может понадобиться...

понедельник, 14 января 2008 г.

А теперь на Ruby

Сегодня я реализовал на Ruby ту же программу для копирования с пропусками, что ранее сделал на Tcl. На Ruby получилось следующее:



require 'find'
require 'fileutils'
#счётчики количества файлов и папок
file_count = 0
dir_count = 0

if(ARGV.size != 2)
puts "Script usage:"
puts "ruby no_svn_copy.rb source destination"
end

#получаем и нормализуем пути
src = File.expand_path(ARGV[0])
dst = File.expand_path(ARGV[1])
puts src + ' => ' + dst

#обрабатываем всё что есть в директории src
Find.find(src) do |path|
if(path.scan(".svn").size != 0)
next
end
#формируем путь к цели
filename = dst + path.gsub(src, '')

puts path
#если это директория, то создаём её в новом месте
if (FileTest.directory?(path))
dir_count += 1
FileUtils.mkdir_p filename
end
#если файл, то копируем его
if (FileTest.file?(path))
file_count += 1
FileUtils.cp path, filename
end
end
#выводим статистику
puts "dirs: " + dir_count.to_s +
" files: " + file_count.to_s



Основное отличие программы на Ruby от Tcl заключается в том, что я использовал возможности модуля Find, что позволило сразу получить список всех исходных файлов и папок, а затем обойти его в цикле, а не делать это самостоятельно с помощью рекурсии. Время выполнения в обоих случаях примерно одинаковое.

SVN и копирование проекта

Системы контроля версий вещь крайне полезная для работы в команде (и не только). В нашей компании используется svn. Под контролем обычно находятся не только исходные файлы, но и всяческие ресурсы, что создаёт определённые неудобства при подготовке версий для мэйлстоунов. Приходится копировавть папку с ресусрсами, а потом удалять все служебные svn-файлы. Дабы немного упростить себе жизнь, я написал небольшой скрипт на Tcl для копирования с исключением папок .svn.


#переменные для подсчёта количества
#файлов и директорий
set files_count 0
set dirs_count 0

proc copy_files {dir_name parent_dir} {
global files_count
global dirs_count
set target $parent_dir/[file tail $dir_name]
puts "d $target => $target"
file mkdir $target
#получаем список фалов в директории
set files [glob -nocomplain -types f $dir_name/*]
#получаем список поддиректорий в директории
set dirs [glob -nocomplain -types d $dir_name/*]

incr dirs_count

#копируем файлы
foreach f $files {
puts "\tf $f => $target/[file tail $f]"
incr files_count
file copy -force $f $target
}
#рекурсивно обрабатываем все
#поддиректории кроме .svn
foreach d $dirs {
if {[string match -nocase */.svn $d] } {
continue
}
copy_files $d $target
}
}

#проверяем наличие параметров
if { $argc != 2 } {
puts "Script usage:"
puts "no_svn_copy.tcl source destination"
return
}

set src_dir [lindex $argv 0]
set target_dir [lindex $argv 1]
#нормализуем пути, чтобы и source и destination
#могли содержать как '\', так и '/'
set src_dir [file normalize $src_dir]
set target_dir [file normalize $target_dir]

#провевряем существование директории-источника
if { [file isdirectory $src_dir] == 0 } {
puts "Source dir not exists"
return
}
puts "Copyng $src_dir => $target_dir\n"
#вызываем рекурсивную функцию копирования
copy_files $src_dir $target_dir

puts "$dirs_count dirs, $files_count files"