Evgenii Legotckoi
July 10, 2016, 1:03 p.m.

User Guide #22 - Ruby - Local variables

A local variable has a name starting with a lower case letter or an underscore character (_). Local variables do not, like globals and instance variables, have the value nil before initialization:

  1. ruby> $foo
  2. nil
  3. ruby> @foo
  4. nil
  5. ruby> foo
  6. ERR: (eval):1: undefined local variable or method `foo' for main(Object)

The first assignment you make to a local variable acts something like a declaration. If you refer to an uninitialized local variable, the ruby interpreter thinks of it as an attempt to invoke a method of that name; hence the error message you see above.


Generally, the scope of a local variable is one of

  • proc{...}
  • loop{...}
  • def ... end
  • class ... end
  • module ... end
  • the entire program (unless one of the above applies)

In the next example, defined? is an operator which checks whether an identifier is defined. It returns a description of the identifier if it is defined, or nil otherwise. As you see, *bar

  1. * s scope is local to the loop; when the loop exits,
bar` is undefined.

  1. ruby> foo = 44; print foo, "\n"; defined? foo
  2. 44
  3. "local-variable"
  4. ruby> loop{bar=45; print bar, "\n"; break}; defined? bar
  5. 45
  6. nil

Procedure objects that live in the same scope share whatever local variables also belong to that scope. Here, the local variable bar is shared by main and the procedure objects p1 and p2 :

  1. ruby> bar=0
  2. 0
  3. ruby> p1 = proc{|n| bar=n}
  4. #<Proc:0x8deb0>
  5. ruby> p2 = proc{bar}
  6. #<Proc:0x8dce8>
  7. ruby> p1.call(5)
  8. 5
  9. ruby> bar
  10. 5
  11. ruby> p2.call
  12. 5

Note that the bar=0 at the beginning cannot be omitted; that assignment ensures that the scope of

  1. bar
will encompass p1 and p2 . Otherwise p1 and p2 would each end up with its own local variable bar , and calling p2 would have resulted in that "undefined local variable or method" error.

A powerful feature of procedure objects follows from their ability to be passed as arguments: shared local variables remain valid even when they are passed out of the original scope.

  1. ruby> def box
  2. | contents = 15
  3. | get = proc{contents}
  4. | set = proc{|n| contents = n}
  5. | return get, set
  6. | end
  7. nil
  8. ruby> reader, writer = box
  9. [#<Proc:0x40170fc0>, #<Proc:0x40170fac>]
  10. ruby> reader.call
  11. 15
  12. ruby> writer.call(2)
  13. 2
  14. ruby> reader.call
  15. 2

Ruby is particularly smart about scope. It is evident in our example that the contents variable is being shared between the reader and writer . But we can also manufacture multiple reader-writer pairs using box as defined above; each pair shares a contents variable, and the pairs do not interfere with each other.

  1. ruby> reader_1, writer_1 = box
  2. [#<Proc:0x40172820>, #<Proc:0x4017280c>]
  3. ruby> reader_2, writer_2 = box
  4. [#<Proc:0x40172668>, #<Proc:0x40172654>]
  5. ruby> writer_1.call(99)
  6. 99
  7. ruby> reader_1.call
  8. 99
  9. ruby> reader_2.call
  10. 15

Do you like it? Share on social networks!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • Evgenii Legotckoi
    April 16, 2025, 5:08 p.m.
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    April 12, 2025, 5:12 p.m.
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…