В последнем посте из нашей серии о переходе с .NET на Ruby мы рассмотрели классы . Классы были очень глубокой темой, поскольку между .NET и Ruby существует большое количество классовых различий. В этом посте мы рассмотрим методы и переменные. Сначала мы рассмотрим, как создавать и вызывать методы, затем рассмотрим блоки и некоторые применения блоков, а в завершение рассмотрим типы переменных, которые существуют в Ruby.
Как всегда, мы на самом деле будем сравнивать Ruby с C #, потому что .NET — это фреймворк, а не язык .
методы
Методы Ruby довольно просты, тем более что не нужно беспокоиться о системе типов, что позволяет нам пропустить определение типов параметров и возвращаемых типов методов. Методы в ruby пишутся с использованием ключевого слова def
для запуска определения метода, и они закрываются с помощью ключевого слова end
, например:
def a_method() # this is a Ruby method end
Это очень отличается от метода .NET, который будет выглядеть так:
public void AMethod() { // this is a C# method }
При использовании параметров метода вы пишете их в скобках и разделяете их запятыми:
def a_method(a, b, c) # this method has three parameters a, b, and c end
Как говорилось в предыдущем посте о классах Ruby , поскольку Ruby написан с использованием утиных утилит, вам не нужно объявлять типы данных ваших параметров в определениях методов. Сравните это с .NET:
private void AMethod(int a, int b, int c) { // this method has three parameters: // an integer a, an integer b, and an integer c }
Разница между этими двумя частями кода заключается в количестве символов, которые необходимо написать. Ruby известен как краткий язык, и определения малых методов явно являются одной из вещей, которые делают Ruby таким кратким.
Двигаясь дальше, давайте посмотрим на один из более неясных синтаксисов Ruby. В коде вы можете увидеть методы, определенные без скобок — задыхайтесь!
def a_method a, b, c # this method also has three parameters a, b, and c end
Это совершенно правильный синтаксис, и вы можете использовать его в своем собственном коде. Давайте вернемся назад и перепишем наш первый пример, используя этот синтаксис:
def a_method # No brackets here end
Таким образом, вы можете видеть, что методы Ruby существенно отличаются от .NET. Но прежде чем выпустить в свет несколько ковбойских кодеров, важно рассказать вам о принятой в сообществе практике, а именно: при определении методов опускайте скобки для методов без параметров и используйте скобки, когда у ваших методов есть параметры .
Давайте перейдем к вызовам методов. Они выглядят так же, как и вызовы методов .NET, и их также можно выполнять без скобок:
AMethod(1, 2, 3);
a_method(1, 2, 3) a_method 1, 2, 3
Все приведенные выше строки кода вызывают a_method
с аргументами 1, 2, 3.
Теперь, когда мы закончили с созданием и вызовом методов, давайте разберемся с некоторыми интересными аспектами методов, в которых не хватает C #, и в которых сияет Ruby.
Блоки
Начнем с блоков. Блоки определяются с помощью фигурных скобок или между ключевыми словами do
и end
:
{ puts "A Block" }
do puts "also a block" end
Концептуально блоки похожи на лямбда-выражения в C #, их можно передать в метод, а затем выполнить из контекста этого метода. Это делается с помощью yield:
def a_method puts "begin" yield puts "end" end a_method { puts "block code" }
Какие выводы:
begin block code end
И так же, как методы, блоки могут принимать переменные в них. Это делается с помощью символа канала для разделения имени переменной следующим образом:
def a_method yield("George") end a_method { |name| puts name } #=> George
Эквивалентный код в C # будет выглядеть так:
public static void a_method(Action<string> block) { block("George"); } a_method((name) => System.Console.WriteLine(name));
Блоки активно используются в Ruby, и они позволяют нам реализовывать некоторые полезные функции, такие как оператор использования C #. Например, вот некоторый код для записи в файл на C #:
using (StreamWriter file = new StreamWriter(@"Output.txt")) { file.WriteLine("Line 1"); }
Этот код открывает файл Output.txt
, затем записывает в него « Output.txt
1n» и, наконец, закрывает дескриптор файла. Ruby способен на то же самое, но вместо этого использует блоки для этого:
File.open("Output.txt", "w") do |file| file.write "Line 1" end
Довольно опрятно, не так ли? В приведенном выше коде file
представляет собой переменную ссылку на объект IO
созданный File.open
. Я признаю, что блочный синтаксис Ruby немного более загадочен, чем синтаксис C #, так как в C # вам нужно четко указывать, что вы используете. Это будет небольшим препятствием для вас при изучении Ruby.
Есть много более мощных приложений для блоков. Взять, к примеру, Синатру. Sinatra использует блоки для создания DSL (Domain Specific Language) для своей URL-маршрутизации. Привет, мир Синатры! Пример выглядит так:
get '/hello' do 'hello world' end
В приведенном выше примере get
— это просто вызов метода с блоком, присоединенным к его концу. Это делает маршруты очень простыми для написания в Sinatra и делает код очень легким для чтения, оставаясь при этом выразительным в своей функциональности. RubySource имеет серию из четырех частей о Синатре, которую тоже стоит посмотреть!
В конечном итоге блоки — это всего лишь реализация шаблона стратегии, встроенного в язык Ruby. А поскольку блоки очень легко писать, они широко используются, когда Rubyists пишут свой код.
переменные
Переходя от блоков, давайте сосредоточим оставшуюся часть этого поста на самом базовом элементе Ruby-программы — переменной. Локальные переменные — это переменные, которые вы пишете в своих методах Ruby, которые пишутся так:
a_variable = 2
Эквивалентный код в C #:
var a_variable = 2;
Опять же, нет необходимости сообщать Ruby, какой у вас тип переменной. Ruby понимает это самостоятельно, что делает синтаксис переменной таким же кратким, как и синтаксис метода. Переменные Ruby используют соглашение об именах, называемое регистром змеи. Поэтому вместо использования заглавных букв, как в .NET, чтобы различать слова в переменной, следует использовать подчеркивание. Переменные ниже являются допустимыми именами переменных:
variable a_variable a_really_big_variable_name
Переменные, приведенные ниже, все еще являются действительными переменными Ruby, но они нарушают соглашение об именах Ruby, поэтому их не следует использовать.
Variable A_Variable areallybigvariablename
При написании классов в Ruby есть несколько специальных обозначений, чтобы различать локальные переменные и переменные экземпляра. Переменные экземпляра начинаются с символа at: @
. Это значительно отличается от .NET, поэтому стоит сравнить два:
public class Example { private int iv; public Example() { iv = 12; } }
class Example def initialize @iv = 12 end end
В обоих приведенных выше примерах класса переменная экземпляра iv
создается в каждом экземпляре Example
. В Ruby нет явного объявления переменной @iv
, вместо этого, записав присваивание 12
в @iv
Ruby достаточно умен, чтобы определить, что @iv
— это ваша переменная экземпляра.
Помимо переменных экземпляра, в Ruby есть еще один тип переменных, известный как переменные класса. Для тех из вас, кто пришел из мира .NET, это то же самое, что и статическая переменная. Чтобы создать переменную класса, вы используете двойной символ: @@
. Следующие примеры кода эквивалентны:
public class Example { private static int id = 42; public static int GetId() { return id; } }
class Example @@id = 12 def self.get_id @@id end end
Также стоит отметить, что в Ruby также есть глобальные переменные. Они начинаются со знака доллара: $
. С глобальными переменными вы вряд ли столкнетесь, когда начнете изучать Ruby, поэтому я не буду перечислять существующие переменные, однако в Руководстве пользователя Ruby есть список глобальных переменных .
И вот где мы подведем этот пост к концу. К концу этого поста вы сможете создавать методы, вызывать методы, использовать блоки и знать о 3 типах переменных в Ruby. На данный момент, если вы следили за этой серией, у вас есть базовые строительные блоки для начала написания собственных программ на Ruby. У вас есть среда для работы , классы для работы и теперь методы и переменные для построения ваших подпрограмм.
В следующей статье мы немного разберемся с ведением Ruby и рассмотрим инструменты, которые вы можете использовать, чтобы ваши Ruby-программы были читабельны и поддерживались другими Rubyists. Мы затронем такие темы, как Соглашения об именах, Комментарии, Документация и Пространство имен, поэтому обязательно зайдите на этот пост!