вторник, 28 февраля 2012 г.

Знакомство с руби

Интерпритируемый язык с функциональной и обьектно-ориентированной концепцией. Создан японцем Yukihiro Matsumoto ("Matz"), первый релиз вышел в 1995, с мыслью, чтобы язык был ориентирован на человека, а не на машину. Он должен был быть мощнее Perl и более обьектно-ориентированный чем python.

Интерпритатор написан на С и имеет название Matz's Ruby Interpreter or Ruby MRI (also called CRuby). Он достаточно медленный, что является главным недостатоком руби.

 Koichi Sasada решил переписать интерпритатор и открыл проект YARV (Yet another Ruby VM). Этот интерпритатор дал прирост на 15%, но стартап руби остается достаточно меделенным, как и работа с базой через ActiveRecord.

Matsumoto в 2007 году смерджил проект YARV со своим кодом, и YARV входит в официальный руби с версии 1.9. YARV после этого прозвали KRI (Koichi's Ruby Interpreter.


Все в руби обьекты. Переменные не имеют типа, а значения всегда. Тоесть переменная может менять в себе значения разных типов напротяжении программы.

Интересности:

1. Блоки кода(code block) имеют два одинаковых синтаксиса:

{ puts "Hello, World!" } # Note the { braces }
#or
do
  puts "Hello, World!"
end
Хорошая книга по сути: http://ruby-doc.org/docs/ProgrammingRuby/html/index.html

А вот еще: http://www.techotopia.com/index.php/Ruby_Essentials

2. В руби все обьекты. Все обращения и опереаторы это работа с методом обьекта send:

my_str.length      =>        my_sqr.send(:length)

1 +2               =>        1.send(:+, 2)

my_array[4]        =>         my_array.send(:[], 4)

my_array[3]="foo"  =>         my_array.send(:[]=, 3, "foo")

if(x==3)...        =>         if(x.send(:==, 3))..........

my_func(z)         =>         self.send(:my_func, z) //обращение из обьекта своему методу


В руби восновном нет операторов языка, это все вызом методов обьекта

Отличие метода Array#+ от Array#<< у обьекта эррей:

y= [1,2]

y= y+["foo",:bar]    =>  y==[1,2,"foo",:bar]

y<<5           =>  y==[1,2,"foo",:bar, 5]

y<<[6,7]       =>  y==[1,2,"foo",:bar, 5, [6,7]]    



3. Хэши

h = {"stupid" => 1, :example=> "foo" }

h.has_key?("stupid") # => true

h["not a key"] # => nil

h.delete(:example) # => "foo"





3. Поэтический режим (poetry mode)  
- используются хеши для передачи параметров по ключам, как в явакрипте параметры передаются не в порядке их определения как формальных аргументов фукнции при декларации, а по имени.        
- Если метод принимает два аргумента и последний является хешем, то можно убрать фигурные скобки хеша.
- Если все без скобок, то можно убрать скобки метода

link_to("Edit”,{:controller=>'students', :action=>'edit'})

link_to "Edit", :controller=>'students', :action=>'edit'





Вот еще одно яркое применение поетри мода:

a.should(be.send(:>=,7))

a.should(be() >= 7)

a.should be >= 7




4. OOP

class SavingsAccount < Account # inheritance
  # constructor used when SavingsAccount.new(...) called
  def initialize(starting_balance=0) # optional argument
    @balance = starting_balance
  end
  def balance # instance method
    @balance
    # instance var: visible only to this object
  end
  def balance=(new_amount) # note method name: like setter
    @balance = new_amount
  end
  def deposit(amount)
    @balance += amount
  end
  @@bank_name = "MyBank.com" # class (static) variable
  # A class method
  def self.bank_name # note difference in method def (это аналог статического метода)
  # почему пишут селф? это какбудто инстанция? да это инстранция но класса
  # ведь в руби все обьекты, а класс это обьект который создает другие обьекты
    @@bank_name
  end
# or: def SavingsAccount.bank_name ; @@bank_name ; end
end

А вот короткая форма:
class SavingsAccount < Account
  def initialize(starting_balance)
    @balance = starting_balance
  end
  attr_accessor :balance
end 
attr_accessor - это не часть языка, это метод обьекта класс, и это метапрограммирование, на самом деле, этот метод просто генерит предыдущий наш код с многословным созданием сеттера и геттера:) А вот пример испльзования инстанс-метода. Например определяем метод в классе:
class String
  def curvy?
    !("AEFHIKLMNTVWXYZ".include?(self.upcase))
  end
end
А обращаться к нему нужно через инстанцию такого класса:
"foo".curvy?

 5. Метапрограмирование

Пример использования метода рут-класса method_missing:
# metaprogramming to the rescue!
class Numeric
  @@currencies = {'yen' => 0.013, 'euro' => 1.292, 'rupee' => 0.019}
  def method_missing(method_id)
    singular_currency = method_id.to_s.gsub( /s$/, '')
    if @@currencies.has_key?(singular_currency)
      self * @@currencies[singular_currency]
    else
      super
    end
  end
end
В итоге мы получаем следующую возможность
acct.deposit(1.euro)
acct.deposit(1000.yen)
acct.deposit(3000.rupees)

6. Деструктивные методы. Если мы ставим знак восклицания возле метода, тогда метод применяется не на копии, а не посредсвенно на обьект.

x = ['apple','cherry','apple','banana']

x.sort # => ['apple','apple','banana','cherry']

x.uniq.reverse # => ['banana','cherry','apple']

x.reverse! # => modifies x

7. Регулярные выражения
  • /i makes the regex match case insensitive.
  • /m makes the dot match newlines. Ruby indeed uses /m, whereas Perl and many other programming languages use /s for "dot matches newlines".
  • /x tells Ruby to ignore whitespace between regex tokens.
  • /o causes any #{...} substitutions in a particular regex literal to be performed just once, the first time it is evaluated. Otherwise, the substitutions will be performed every time the literal generates a Regexp object.

Комментариев нет:

Отправить комментарий