_If you wish to report errors or suggest improvements for this FAQ,
please go to our
[GitHub repository](https://github.com/ruby/www.ruby-lang.org/)
and open an issue or pull request._


## Синтаксис

### В чем разница между непосредственным значением и ссылкой?
{: #immediate}

<div class="not-prose bg-ruby-100 dark:bg-ruby-800 rounded-lg p-8 my-6">
  <div class="flex items-start gap-3">
    <svg class="w-6 h-6 text-ruby-700 dark:text-ruby-200 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
      <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
    </svg>
    <p class="text-sm text-ruby-700 dark:text-ruby-200 italic">
      This section or parts of it might be out-dated or in need of confirmation.
    </p>
  </div>
</div>


`Fixnum`, `true`, `nil` и `false` реализованы как непосредственные (immediate) значения. В случае непосредственных значений переменные хранят сами объекты, а не ссылки на них.

Для таких объектов нельзя определить синглтон-методы. Два объекта `Fixnum` с одинаковым значением всегда представляют один и тот же экземпляр объекта, поэтому (например) переменные экземпляра для `Fixnum` со значением `1` разделяются между всеми `1` в системе. Это делает невозможным определение синглтон-метода только для одного из них.

### В чем разница между `nil` и `false`?

Сначала о сходстве: `nil` и `false` — единственные два объекта, которые в булевом контексте вычисляются как `false`. (Другими словами: это единственные «ложные» значения, все остальные объекты являются «истинными»).

Однако `nil` и `false` являются экземплярами разных классов (`NilClass` и `FalseClass`) и ведут себя по-разному в остальных случаях.

Мы рекомендуем, чтобы предикатные методы (те, чье имя заканчивается вопросительным знаком) возвращали `true` или `false`. Другие методы, которым нужно указать на ошибку или отсутствие результата, должны возвращать `nil`.

### Почему пустая строка не является `false`?

В: Пустая строка (`""`) возвращает `true` в условном выражении! В Perl она ложна (`false`).

О: Но Ruby — это не Perl ;-). Все очень просто: в Ruby только `nil` и `false` являются ложными в контексте условий.

Вы можете использовать `empty?`, сравнивать строку с `""` или сравнивать `size` или `length` строки с `0`, чтобы узнать, пуста ли она.

### Что означает `:name`?

Двоеточие, за которым следует имя, создает объект Symbol (символ), который однозначно соответствует этому идентификатору. В течение времени выполнения программы для одного и того же имени или строки будет создаваться один и тот же объект Symbol. Символы также можно создавать с помощью `"name".intern` или `"name".to_sym`.

Объекты Symbol могут представлять идентификаторы для методов, переменных и так далее. Некоторые методы, такие как `define_method`, `method_missing` или `trace_var`, требуют символ. Другие методы, например `attr_accessor`, `send` или `autoload`, также принимают строку.

Благодаря тому, что они создаются только один раз, символы часто используются в качестве ключей хеша. Строковые ключи хеша создавали бы новый объект при каждом использовании, что приводило бы к некоторым накладным расходам памяти. Для ключей хеша в виде символов существует даже специальный синтаксис:

~~~
person_1 = { :name => "John", :age => 42 }
person_2 = { name: "Jane", age: 24 }        # альтернативный синтаксис
~~~

Символы также можно использовать в качестве перечисляемых значений или для присвоения уникальных значений константам:

~~~
status = :open  # :closed, ...

NORTH = :NORTH
SOUTH = :SOUTH
~~~

### Как я могу получить доступ к значению символа?

Чтобы получить значение переменной, соответствующей символу, вы можете использовать `symbol.to_s` или `"#{symbol}"`, чтобы получить имя переменной, а затем выполнить `eval` в области видимости символа, чтобы получить содержимое переменной:

~~~
a = "This is the content of `a'"
b = eval("#{:a}")
a.object_id == b.object_id  # => true
~~~

Вы также можете использовать

~~~
b = binding.local_variable_get(:a)
~~~

Если ваш символ соответствует имени метода, вы можете использовать `send`:

~~~
class Demo
  def hello
    "Hello, world"
  end
end

demo = Demo.new
demo.send(:hello)
~~~

Или вы можете использовать `Object#method`, чтобы вернуть соответствующий объект `Method`, который затем можно вызвать:

~~~
m = demo.method(:hello)  # => #<Method: Demo#hello>
m.call                   # => "Hello, world"
~~~

### Является ли `loop` структурой управления?

Хотя `loop` выглядит как структура управления, на самом деле это метод, определенный в `Kernel`. Следующий за ним блок вводит новую область видимости для локальных переменных.

### В Ruby нет цикла с постусловием

В: В Ruby нет конструкции `do { ... } while`, так как же мне реализовать циклы, проверяющие условие в конце?

О: Clemens Hintze говорит: Вы можете использовать сочетание `begin ... end` и модификаторов инструкций `while` или `until` для достижения того же эффекта:

~~~
i = 0
begin
  puts "i = #{i}"
  i += 1
end until i > 4
~~~

Результат:

~~~
i = 0
i = 1
i = 2
i = 3
i = 4
~~~

### Почему я не могу передать литерал хеша в метод: `p {}`?

`{}` парсится как блок, а не как конструктор `Hash`. Вы можете заставить `{}` рассматриваться как выражение, сделав факт того, что это параметр, явным: `p({})`.

### Я не могу заставить `def pos=(val)` работать!

У меня есть следующий код, но я не могу использовать метод `pos = 1`.

~~~
def pos=(val)
  @pos = val
  puts @pos
end
~~~

Методы с приписанным `=` должны вызываться с явным получателем (без получателя вы просто присваиваете значение локальной переменной). Вызывайте его как `self.pos = 1`.

### В чем разница между `'\1'` и `'\\1'`?

Они имеют одинаковое значение. В строке в одинарных кавычках только `\'` и `\\` трансформируются, а другие комбинации остаются без изменений.

Однако в строке в двойных кавычках `"\1"` — это байт `\001` (восьмеричный битовый паттерн), в то время как `"\\1"` — это строка из двух символов, содержащая обратный слэш и символ `"1"`.

### В чем разница между `..` и `...`?

`..` включает правую границу в диапазон, `...` — нет:

~~~
(5..8).to_a   # => [5, 6, 7, 8]
(5...8).to_a  # => [5, 6, 7]
~~~

### В чем разница между `or` и `||`?

В: `p(nil || "Hello")` выводит `"Hello"`, в то время как `p(nil or "Hello")` выдает ошибку парсинга. Почему?

О: `or` имеет очень низкий приоритет, `p( (nil or "Hello") )` будет работать.

Приоритет `or`, например, также ниже, чем у `=`, в то время как у `||` приоритет выше:

~~~
foo = nil || "Hello"  # парсится как: foo = (nil || "Hello")
foo  # => "Hello"

# но, возможно, это удивительно:

foo = nil or "Hello"  # парсится как: (foo = nil) or "Hello"
foo  # => nil
~~~

`or` (и аналогично `and`) лучше всего использовать **не** для объединения булевых выражений, а для управления потоком выполнения, например:

~~~
do_something  or raise "some error!"
~~~

где `do_something` возвращает `false` или `nil` при возникновении ошибки.

### Есть ли в Ruby указатели на функции?

Объект `Proc`, созданный с помощью `Proc.new`, `proc` или `lambda`, может быть доступен через переменную, так что эту переменную можно назвать указателем на функцию. Вы также можете получить ссылки на методы внутри конкретного экземпляра объекта, используя `object.method`.

### В чем разница между `load` и `require`?

`load` загружает и выполняет программу на Ruby (`*.rb`).

`require` также загружает программы на Ruby, но кроме того загружает бинарные модули расширения Ruby (разделяемые библиотеки или DLL). В дополнение к этому, `require` гарантирует, что функциональность никогда не будет загружена более одного раза.

### Есть ли в Ruby обработка исключений?

Ruby поддерживает гибкую схему обработки исключений:

~~~
begin
  statements which may raise exceptions
rescue [exception class names]
  statements when an exception occurred
rescue [exception class names]
  statements when an exception occurred
ensure
  statements that will always run
end
~~~

Если в блоке `begin` возникает исключение, выполняется блок `rescue` с соответствующим именем исключения. Блок `ensure` выполняется независимо от того, возникло исключение или нет. Блоки `rescue` и `ensure` могут быть опущены.

Если для блока `rescue` не указан класс исключения, подразумевается исключение `StandardError`, и перехватываются исключения, находящиеся в отношении `is_a?` к `StandardError`.

Это выражение возвращает значение блока `begin`.

Последнее исключение доступно через глобальную переменную `$!` (и, таким образом, его тип можно определить с помощью `$!.type`).
