середа, 26 вересня 2007 р.

rmovie

rmovie є розширенням Ruby, яке надає методи для доступу до файлів мультимедіа (зокрема відео файлів), він може повертати кадри відео, як малюнки, які в подальшому можна імпортуватися до RMagick. Це дозволяє створювати ескізи малюнків із фільмів. rmovie також корисний для звіту про тривалість і бітрейт аудіо файлів (mp3, wma ...). rmovie має доступ до багатьох відео форматів, які підтримуються ffmpeg (avi, mpg, wmv, mov).

Насамперед пересвідчіться, що Ruby встановлений у вашій системі (тут використовується Ubuntu):
$ sudo apt-get install ruby1.8
$ sudo apt-get install ruby1.8-dev
$ sudo apt-get install rubygems

Для того щоб rmovie працював необхідно встановити також вихідні коди libavcodec і libavformat:
$ sudo apt-get install ffmpeg
$ sudo apt-get install libavcodec-dev
$ sudo apt-get install libavformat-dev


Для того щоб витягувати кадри відео необхідно встановити RMagick:
$ sudo apt-get install librmagick-ruby


Встановити rmovie можна декількома способами:
Спосіб 1.
$ wget http://files.rubyforge.mmmultiworks.com/rmovie/rmovie-0.5.1.gem
$ gem install rmovie-0.5.1.gem

Спосіб 2.
$ gem install rmovie
Building native extensions. This could take a while...
Successfully installed rmovie, version 0.5.1


Невеликий приклад використання rmovie спільно з RMagick

require 'rubygems'
require 'rmovie'
require 'RMagick'
mov = RMovie::Movie.new("movie.avi")
mov.duration # => 5440.43994140625
mov.frame_count # => 136011
mov.frame_width # => 672
mov.frame_height # => 384
mov.has_audio? # => true
mov.file_name # => "/media/sdb5/films/movie.avi"
frame = mov.frame(10)
img = Magick::Image.new(frame.width, frame.height) # => 672x384 DirectClass 16-bit
img.import_pixels(0, 0, frame.width, frame.height, "RGB", frame.to_string, Magick::CharPixel) # => 672x384 DirectClass 16-bit
img.write("output.jpg") # => output.jpg 672x384 DirectClass 16-bit 16kb


За більш докладнішою документацією зверніться до rmovie API Documentation та RMagick Documentation

Область застосування зв'язки rmovie + RMagick обмежує тільки ваша фантазія. Enjoy!

вівторок, 18 вересня 2007 р.

Качина типізація

Латентна, неявна або качина типізація (калька з англ. Duck typing) - вид динамічної типізації, яка використовується в деяких мовах програмування (Smalltalk, Python. Ruby, Boo), коли значення змінної визначає, те що вона може робити. Тобто є об'єкт, який реалізує інтерфейс, якщо він містить всі методи цього інтерфейсу, незалежно від зв'язків в ієрархії наслідування.
Англійська назва посилається на "качиний тест" (duck test) - "If a bird looks like a duck, swims like a duck and quacks like a duck, then it's probably a duck." ("Якщо птах виглядає як качка, плаває як качка і крякає як качка, це ймовірно і є качка").
Качина типізації піклується тільки про ті аспекти об'єкта, які використовуються, замість типу об'єкту безпосередньо.Наприклад, у мові без качиної типізації, можна створити функцію яка бере об'єкт Duck (Качка) і викликає його методи swim (плавати) quack (крякати). У мові з качиною типізацією, еквівалентна функція може взяти об'єкт будь-якого типу і викликати методи "плавати" і "крякати". Якщо об'єкт немає методів до яких звертаються, функція сигналізує run-time error (помилку виконання) .
Качина типізація - це фундаментальна частина мови програмування Ruby. Можна відмітити Ruby, не оголошує види змінних чи методів - все є тільки деяким видом об'єкту. Об'єкти Ruby (на відміну від об'єктів у деяких інших об'єктно-орієнтованих мовах) можуть бути змінені індивідуально. Ви завжди можете додавати методи до об'єкта. В Ruby поведінка і можливості об'єкту можуть відрізнятися від тих, що забезпечуються його класом.
В Ruby ми залежимо менше від типу (або класу) об'єкту і більше від його можливостей (методів). Відтепер, качина типізація має на увазі тип об'єкту, як те що з ним можна зробити, а не те, чим є об'єкт. Качина типізація посилається на тенденцію Ruby менше турбуватися про клас об'єкта, і більше концентруватися на його методах.
Якщо об'єкт плаває як качка і крякає як качка, то інтерпретатор Ruby щасливий розглядати його, ніби то це качка.
Розглянемо наступний приклад:
# Check whether the object defines the to_str method
puts ('A string'.respond_to? :to_str) # => true
puts (Exception.new.respond_to? :to_str) # => true
puts (4.respond_to? :to_str) # => false

Вищеописаний приклад - це найпростіший приклад філософії "качиної типізації"в Ruby, якщо об'єкт крякає як качка (або діє як рядок(String)), розглядати його як качку (або рядок(String)). При першій-ліпшій можливості, ви повинні розглядати об'єкт згідно методів, які він визначає, замість класів з яких він успадковується або модулів, у які він включений.
Шоб краще зрозуміти качину типізацію введемо наступні три класи - Duck, Goose і DuckRecording.

class Duck
def quack
'Quack!'
end
def swim
'Paddle paddle paddle...'
end
end

class Goose
def honk
'Honk!'
end
def swim
'Splash splash splash...'
end
end

class DuckRecording
def quack
play
end
def play
'Quack!'
end
end

def make_it_quack(duck)
duck.quack
end

puts make_it_quack(Duck.new) # => Quack!
puts make_it_quack(DuckRecording.new) # => Quack!

def make_it_swim(duck)
duck.swim
end

puts make_it_swim(Duck.new) # => Paddle paddle paddle...
puts make_it_swim(Goose.new) # => Splash splash splash...

Метод який вказує Качці (Duck) крякати, працює і для DuckRecording завдяки качиній типізації. Як і метод, який вказує Качці (Duck) плавати, буде працювати і для Гуски (Goose).

Використанні ресурси:
http://en.wikipedia.org/wiki/Duck_typing
http://rubylearning.com/satishtalim/duck_typing.html
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/100511

четвер, 13 вересня 2007 р.

Apache 2 + Ruby 1.8 + mod_ruby + eruby

В цій статі ми розглянемо встановлення і настройку Web-сервера Apache 2, Ruby 1.8 (mod_ruby + eruby) для використання на локальній машині під ОС Linux (Ubuntu/Debian).

Інсталяція:
Для початку необхідно встановити всі необхідні пакети:

$ sudo apt-get install ruby
$ sudo apt-get install apache2
$ sudo apt-get install libapache2-mod-ruby eruby


Я буду використовувати конфігурацію Apache "по замовчуванню".
Після інсталяції mod_ruby, автоматично буде створений файл /etc/apache2/mods-available/ruby.load з таким вмістом:
LoadModule ruby_module /usr/lib/apache2/modules/mod_ruby.so

Настройка:
В дистрибутивах Ubuntu/Debian(можливо і в інших) конфігураційний файл httpd.conf розбитий на велику кількість менших файлів у директорії /etc/apache2.
Для конфігурації mod_ruby створимо файл /etc/apache2/mods-available/ruby.conf. Також необхідно створити посилання на нього до каталогу /etc/apache2/mods-enabled, щоб він завантажувався автоматично.
sudo ln -s /etc/apache2/mods-available/ruby.conf /etc/apache2/mods-enabled/ruby.conf

З докладним описом процесу інсталяції і настройки можна ознайомитися тут .

Я буду використовувати зв'язку eRuby + mod_ruby.
eruby - це виконання eRuby(Embedded Ruby), що служить для включення коду Ruby у HTML та інші документи. Має розширення *.rhtml. Код включається за допомогою пари роздільників "<%" і "%>". Коли мене запитують про eRuby, я завжди відповідаю що це типу PHP, тільки для Ruby :). Докладніше про eRuby тут i тут .
Додамо наступні рядки до /etc/apache2/mods-available/ruby.conf.
<IfModule mod_ruby.c>
RubyRequire apache/eruby-run

# Обробляти файлами з директорій /eruby як файли eRuby
<Location /eruby>
SetHandler ruby-object
RubyHandler Apache::ERubyRun.instance
</Location>

# Обробляти *.rhtml файли як eRuby файли
<Files *.rhtml>
SetHandler ruby-object
RubyHandler Apache::ERubyRun.instance
</Files>
</IfModule>

<Directory /var/www/eruby>
AllowOverride All
Options ExecCGI
Order allow,deny
Allow from all
</Directory>

AddType text/html .rhtml


Існує одна проблема, коли ви здійснюєте запит до директорії(наприклад, http://localhost/eruby), mod_ruby викликає помилку (щось типу /usr/lib/ruby/1.8/apache/eruby-run.rb:101:in `compile_file': Is a directory - /var/www/eruby/ (Errno::EISDIR). Щоб виправити це додамо наступний рядок до ruby.conf .
RedirectMatch ^/eruby/?$ /eruby/index.rhtml


Перезапустимо веб-сервер командою:
$ sudo /etc/init.d/apache2 restart


Створимо файл /var/www/eruby/index.rhtml:
<%= Time.now %>

Перейдемо у Web-броузері за адресою http://localhost/eruby і побачимо поточну дату і час.
Вуаля, готово!

Відображення помилок mod_ruby:
mod_ruby не терпить невдачу з попередженнями(warnings) і повідомлення про попередження не записуються до log-файлу (наприклад, /var/log/apache2/error.log чи будь-який інший), тільки повідомлення про помилки записуються до цього файлу. Так що забудьте про попередження під mod_ruby. Можливо є якийсь діагностичний рівень, на якому це можна встановити, але мені не відомо про це :(.
Коли Ruby зазнає синтаксичну або іншу помилку він повертає "Internal Server Error (500)" і повідомлення про помилку записується до log-файлу Apache. Щоб постійно слідкувати за помилками доводиться читати цей файл або використовувати утиліту tail:
$ sudo tail -f /var/log/apache2/error.log

Постійно доводиться переключатися у консоль, шо не дуже зручно у процесі написання коду.
Для виведення помилок на Web-сторінку використовується опція ErrorDocument Apache.
Створимо файл /var/www/eruby/errors/error_500.rhtml:
<%
r = Apache.request
r.content_type = "text/plain"
r.send_http_header
print "Ruby Error: ",r.prev.uri,"\n\n"
print r.prev.error_message
%>


І додамо у /etc/apache2/mods-available/ruby.conf наступний рядок.
ErrorDocument 500 /eruby/errors/error_500.rhtml


Перезапустимо Apache:
$ sudo /etc/init.d/apache2 restart


Тепер при виникненні помилки(але не попередження) фактичне повідомлення про невдачу буде показане не сторінці. Рекомендую використовувати даний метод лише під час розробки і відналагодження.