21 марта 2012 г.

Ruby глазами Java-программиста

Программист должен быть любознательным и всегда с радостью воспринимать что-то новое. Именно поэтому я решил помимо знакомого мне Grails посмотреть на тот фреймворк, который был вдохновителем для его создания - Ruby on Rails. Но перед тем, как углубляться в фреймоврк было бы неплохо знать язык, который он использует. Сам по себе язык Ruby крайне простой, но мне, как C/Java программисту, он первое время показался просто мозговыносящим. Но если не держаться за старый опыт и открыться простоте Ruby то тогда всё получится :) В этой заметке я бы хотел привести моменты, которые меня особенно удивили.


1
Параметры класса задаются крайне эффектным способом. Если вы хотите чтобы они были только для чтения, то используется ключевой слово attr_reader, если только для записи - attr_writer, а если и для чтения и для записи - attr_accessor. Например:
class MyClass
    attr_accessor :param1, :param2
end

2
В условиях значение nil рассматривается как false, а все остальные - как true. Таким образом:
if 0
    print "O_o"
end
напечатает "O_o".

3
Наследование делается так (довольно симпатично, имхо):
class Parent
    attr_accessor :name
end

class Child < Parent
end

4
В Ruby активно применяются такие вот, на мой взгляд, "вывернутые" условия:
<действие> if <условие>
<действие> unless <условие>

5
Зато есть кортеджи, как в Python и это просто праздник какой-то :) Например можно создавать такие вот конструкции:
rho, theta = MyClass.getPolars(x,y)

6
Можно писать так:
1.upto(5) { |number| puts number }
а можно так:
1.upto(5) do |number|
    puts number
end
Один и тот же результат добивается двумя разными констркциями языка. По-моему это бардак.

7
Если имя переменной начинается с большой буквы, то её значение - константа.

8
Для определения многострочных стрингов используется конструкция:
x = %q<спец.символ><текст><спец.символ>
Где в качестве спец.символа может выступать !,|,{} и прочие штуки, которые только могут прийти в голову, например:
x = %q|this
works|
а еще прикольнее можно написать так:
x = <<END_STRING
nanana
lalala
END_STRING
и это тоже будет многострочной стрингой.

9
Зачем-то переименован оператор switch. В Ruby он пишется так:
case <выражение>
    when <значение>
        <действие>
    when <значение>
        <действие>
    else
        <действие>
end
Кстати, в тему про переименования: стандартная для многих языков конструкция try..catch имеет вид begin..rescue..end. Создается впечатление, что авторы Ruby хотели просто сделать язык таким, чтобы не как у всех. И у них получилось. Только вот зачем они отошли от стандартных имен лично мне не ясно.

10
Помимо while есть еще оператор until. Работает аналогично. Не перестаю удивляться как много практически одинаковых операторов понапридумывали в Ruby. Причем их можно использовать как стандартным способом:
until x > 0
    puts x
    x -= 1
end
Так и в одну строчку:
x = x * 2 until x >100

11
Символы. Это отдельная песня. Это переменные, которые не имеют значения, и которые инициализируются только один раз. Значит такой код:
mood = :good
puts "Yeah!" if mood == :good
создаст один экземлпяр символа :good. А если мы заменим символ на строку "good", то работа программы не изменится, но будет создано два экземпляра строки. Их применяют в создании map-ов. Например так:
person1 = { :name => "Bob", :age => 30 }
person2 = { :name => "Mark", :age => 23 }

12
Конструктор класса всегда называется initialize. Он вызывается автоматически при вызове new. Причем создать 2 конструктора с разным набором параметров у меня не получилось - видится только последний. Странное, имхо, решение создателя языка.

13
Статические методы реализуются так:
class MyClass
    def self.static_method
        ...
    end
    ...
end

14
По умолчанию область видимости элементов класса - public, если хочется чего-то другого - просто напишите это перед объявлением параметров или методов и их область видимости изменится. Например:
class MyClass
    def method1
        ...
    end

    private

    def method2
        ...
    end
end
Метод method2 не будет виден извне класса. Казалось бы всё просто, но тут опять мы встречаем великолепие Ruby с его возможностями решать одну и ту же задачу 1001 способами. Можно написать так:
class MyClass
    def method1
        ...
    end

    def method2
        ...
    end

    protected :method2
end
и метод method2 станет protected.

15
Довольно интересен так же способ обращения ко внутренним классам. Вот как это выглядит:
class MyClass
    class InnerClass
    end
end
a = MyClass::InnerClass.new

16
Функциональность может быть внедрена в класс не только через наследование от суперкласса (кстати, множественного наследования в Ruby нет), но и через включения. Делается так:
module CoolFeatures
    def class_name
        self.class.to_s
    end
end

class MyClass
    include CoolFeatures
end
Теперь MyClass содержит метод class_name, который при вызове вернёт MyClass. Такая вот магия.

17
Есть такой интересный класс-конструктор Struct, который используется для создания классов для хранения данных:
Person = Struct.nex(:name, :phone)
john = Person.new("John", 2161)

Конечно можно еще очень долго удивляться возможностям и синтаксису Ruby, но одно можно сказать точно - язык крайне интересный и если у вас будет настроение узнать что-либо совершенно инопланетное, то на него стоит обратить внимание.

1 комментарий:

  1. begin, until в Pascal используэтся часто...
    Популярность Ruby очень растет
    http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-jfokus-2012

    ОтветитьУдалить

Примечание. Отправлять комментарии могут только участники этого блога.