Давайте напишем функцию вычисления факториалов. Математическое определение факториала от n следующее:
n! = 1 (когда n==0) = n * (n-1)! (иначе)
В Ruby это может быть записано следующим образом:
def fact(n) if n == 0 1 else n * fact(n-1) end end
Вы можете заметить, что оператор end здесь повторяется. Ruby из-за этого называют Алоголо-подобным. (На самом деле синтаксис Ruby больше походит на синтаксис языка Eiffel.) Вы можете также заметить, что отсутствует оператор return . Он не требуется поскольку Ruby возвращает последнее значение с которым вышел из функции. Использование оператора return возможно, но не обязательно. Давайте опробуем вывод нашего факториала. Добавим одну строку кода, которая даст нам рабочую программу с выводом:
# Программа находит факториал от числа # Сохраните этот файл как fact.rb def fact(n) if n == 0 1 else n * fact(n-1) end end print fact(ARGV[0].to_i), «n»
Здесь присутствует массив ARGV, который содержит аргументы команды, и конвертирование символов строки в целочисленную переменную (integer).
Стоит ли выбирать Язык Программирования RUBY?
% ruby fact.rb 1 1 % ruby fact.rb 5 120
Давайте запустим программу с аргументом 40. Это может привести Ваш калькулятор к переполнению.
% ruby fact.rb 40 815915283247897734345611269596115894272000000000
Но это работает. На самом деле, Ruby может работать с любым целым числом, с которым позволяет работать память компьютера. Итак число 400! Можем вычислить факториал и для него:
% ruby fact.rb 400 64034522846623895262347970319503005850702583026002959458684 44594280239716918683143627847864746326467629435057503585681 08482981628835174352289619886468029979373416541508381624264 61942352307046244325015114448670890662773914918117331955996 44070954967134529047702032243491121079759328079510154537266 72516278778900093497637657103263503315339653498683868313393 52024373788157786791506311858702618270169819740062983025308 59129834616227230455833952075961150530223608681043329725519 48526744322324386699484224042325998055516106359423769613992 31917134063858996537970147827206606320217379472010321356624 61380907794230459736069956759583609615871512991382228657857 95493616176544804532220078258184008484364155912294542753848 03558374518022675900061399560145595206127211192918105032491 00800000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000
Примеры программ на руби
Вывести список методов объекта
require ‘pp’ pp String.methods
[«private_class_method», «inspect», «name», «tap», «clone», «public_methods», «__send__», «object_id», «method_defined?», «instance_variable_defined?», .
Храним данные вместе с исходным кодом
puts DATA.read __END__ I can put anything I want after the __END__ symbol and access it with the DATA global. Whoa!
ARGF преобразует переданные в виде аргументов имена файлов в единый поток, с которого можно читать данные
Стоит ли выбирать язык программирования Ruby?
# shell> echo «inside a.txt» > a.txt # shell> echo «inside b.txt» > b.txt # shell> cat a.txt b.txt # inside a.txt # inside b.txt # linenum.rb ARGF.each do |line| puts «%3d: %s» % [ARGF.lineno, line] end
shell> ruby linenum.rb a.txt b.txt 1: inside a.txt 2: inside b.txt
Получить колличество переданых аргументов
$ echo ‘puts ARGV.length’ | ruby — one two three
Напечатать сообщение и оборвать выполнение
abort(«Segmentation fault»)
Если session[:cart] не задан — установить значение по умолчанию
session[:cart] ||= default
Проверить есть ли элемент в массиве
if [«a», «b», «c», «d»].include?(‘a’) puts ‘Found it in the array’ end
Found it in the array
Инкремент/декремент в руби. Само значение правда не изменяется.
1.pred #=> 0 (-1).pred #=> -2 1.next #=> 2 (-1).next #=> 0
Корректно обрабатывае нажатие CTRL-C от пользователя
trap(«INT») do puts «Correct exit»; exit end while true do end
Вызвать функцию по имени.
def hello name puts «Hello, #!» end send :hello, :waserd
Hello, waserd!
Обойти файл построчно
$ cat test.rb
i = 0 File.open(‘test.rb’).each do |line| i += 1 print «#t#» end
$ ruby test.rb
1 i = 0 2 File.open(‘test.rb’).each do |line| 3 i += 1 4 print «#t#» 5 end
Определяем функцию для определения функций =_+
def deff name, block) end
Открыв внешнюю команду на выполнение — передавать и читать с неё данные
IO.popen(«pr —columns 3 -at», «r+») do |io| (1..10).each < |i| io.puts «Line #n» > io.close_write puts io.readlines end
$ ./test.rb
Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10
Получаем 1 символ из ввода пользователя, перехватывая нажатия Ctrl и Alt.
def get_char key = «» begin system(«stty raw -echo») f = STDIN.getc if (1..26) === f key = «C-» + (f + 96).chr elsif f == ?e c = STDIN.getc if (1..26) === c key = «C-A-» + (c + 96).chr else key = «A-» + c.chr end else if f >= 208 key = f.chr + STDIN.getc.chr else key = f.chr end end ensure system(«stty -raw echo») end key end while c = get_char exit if c == «q» puts c end
$ ruby test.rb
Ctrl + Alt + w
Output-buffering в ruby. Выполняем код, который печатает в stdout и возвращаем его как строку.
require «stringio» def ob buffer = StringIO.new old_stdout = $stdout $stdout = buffer yield $stdout = old_stdout buffer.rewind buffer.read end v = ob do puts «hello» end v2 = ob do puts «world» end puts v2 + v puts(ob do print «>» r = ob do print «!» end print »
world hello >
Запустить mplayer на воспроизведение файла и передавать ему команды
IO.popen(«mplayer music.mp3 2> /dev/null «, «r+») do |io| while t = gets.chomp io.print t end end
Передаём опции в функцию
require ‘pp’ def foo(opts = <>) opts = :value, :key2 => :value2>.merge(opts) end pp foo pp foo(:bar => :baz, :key => :value3)
:value, :key2=>:value2> :value3, :key2=>:value2, :bar=>:baz>
Игнорируем исключения в блоке кода
def ignore_exception begin yield rescue Exception end end ignore_exception do puts «Ignoring Exception» raise Exception puts «This is Ignored» end puts «This is NOT ignored»
Ignoring Exception This is NOT ignored
Получить один символ и вернуть управление программе. На stackoverflow ещё есть интересные примеры — стоит почитать первоисточник
tty_param = `stty -g` system ‘stty raw’ a = IO.read ‘/dev/stdin’, 1 system «stty #» print a
Число в объект Time
Time.at(1234567890)
=> 2009-02-14 02:31:30 +0300
print . EOF print . EOF print
Устанавливаем mysql соединение через ssh-туннель, авторизуясь по ключам
#!/usr/bin/env ruby require ‘rubygems’ require ‘mysql2’ require ‘net/ssh/gateway’ gateway = Net::SSH::Gateway.new(‘productionserver.ru’, ‘user’, < port: 22, keys: [«id_rsa.pub»], keys_only: true >) port = gateway.open(‘localhost’, 3306, 3307) client = Mysql2::Client.new( host: «127.0.0.1», username: ‘root’, password: ‘qwerty’, database: ‘wp_blog’, port: port ) results = client.query(«show tables») results.each do |row| p row end client.close gateway.shutdown!
- 2-3 — blog.bogojoker.com
- 7 — www.phptoruby.com
- 8 — www.ruby-doc.org
- 9 — www.ruby-forum.com
- 10 — stackoverflow.com
- 18 — stackoverflow.com
- 19 — stackoverflow.com
- 20 — stackoverflow.com
- 21 — www.ruby-doc.org
- hyperpolyglot.org — сравнение между php-perl-python-ruby
Источник: najomi.org
Ruby за двадцать минут
Что если мы хотим сказать “Hello” без утомления наших пальцев? Мы должны создать метод!
irb(main):010:0> def h irb(main):011:1> puts «Hello World!» irb(main):012:1> end => nil
Код def h означает начало объявление метода. Он говорит Ruby, что мы определяем метод, имя которого h . Следующая строка – тело метода, та же строка, что мы видели раньше: puts «Hello World» . И, наконец, последняя строка, end , говорит Ruby, что мы завершили объявление метода. Ответ от Ruby, => nil , говорит нам, что он понял, что мы завершили объявление метода.
Кратко о повторяющихся жизнях метода
Теперь давайте попробуем вызвать метод несколько раз:
irb(main):013:0> h Hello World! => nil irb(main):014:0> h() Hello World! => nil
Ну, это было просто. Вызвать метод в Ruby так же просто, как просто упомянуть его имя в коде.
Если метод не принимает параметры – это все что вам нужно сделать. Вы можете добавить пустые скобки, если вам так нравится, но это не обязательно.
Что если мы хотим сказать hello одному человеку, а не всему миру? Просто переопределим метод h , чтобы он принимал имя как параметр.
irb(main):015:0> def h(name) irb(main):016:1> puts «Hello #name>!» irb(main):017:1> end => nil irb(main):018:0> h(«Matz») Hello Matz! => nil
Итак, это работает… но давайте на секунду задумаемся, что здесь происходит.
Места для интерполяции в String
Что такое # в коде выше? Это способ Ruby вставить что-либо в строку. Кусок кода между фигурными скобками превратится в строку (если это еще не строка) и потом подставится во внешнюю строку в этом месте. Вы также можете использовать это, чтобы убедиться, что имя будет с большой буквы:
irb(main):019:0> def h(name = «World») irb(main):020:1> puts «Hello #name.capitalize>!» irb(main):021:1> end => nil irb(main):022:0> h «chris» Hello Chris! => nil irb(main):023:0> h Hello World! => nil
Вы должны здесь отметить несколько других приемов. Один из них, что мы опять вызываем метод без скобок. Если очевидно то, что вы хотите сделать – скобки не обязательны. Другой прием – это параметр по умолчанию World . Это означает что, “Если имя не передано в качестве параметра, используй параметр по умолчанию World ”.
Эволюционируем в Greeter (Приветствующего)
Что если мы хотим создать реального приветствующего, того кто запомнит ваше имя и поприветствует вас и всегда будет относиться к вам с уважением? Вы можете использовать для этого объект. Давайте создадим класс “Greeter”.
Итак, как мы сможем заставить этот класс Greeter работать? Создадим объект.
Начните сейчас, это легко!
- Попробуйте Ruby! (в своем браузере)
- Ruby за двадцать минут
- В Ruby из других языков
Источник: www.ruby-lang.org