Почему строка внутри класса, но вне методов может быть выполнена в Ruby? - PullRequest
2 голосов
/ 23 февраля 2011

Это задуманная философия дизайна? Например, если у меня есть класс «Greeter», определенный следующим образом:

1: class Greeter
2:   def say_hello
3:     puts "Hello"
4:   end
5: 
6:   puts "Goodbye!"
7: 
8: end

Когда я запускаю файл:

$ ruby greeter.rb
Goodbye!
$

На других языках (например, Java, PHP) я получу сообщение об ошибке, что строка 6 недействительна. Путь Руби чем-то отличается от того, что я знаю об ООП, или я неправильно понимаю концепцию ООП?

Ответы [ 5 ]

3 голосов
/ 23 февраля 2011

Я не понимаю, что это должно делать ООП. ООП - это отправка сообщений, а puts "Goodbye!" - это отправка сообщения. Он отправляет сообщение :puts с единственным аргументом "Goodbye!" на self.

Действительно, не ООП - это строка 2, с которой у вас, похоже, нет проблем, поскольку строка 2 не является отправкой сообщения.

Давайте посмотрим на это с противоположной точки зрения: если бы содержимое тела класса было не выполнено, то как бы вы определили методы? Вы, очевидно, не удивлены тем, что строка 2 выполняется, так почему строка 6 должна трактоваться иначе? Это было бы ужасно противоречиво!

2 голосов
/ 23 февраля 2011

Это не потому, что это объектно-ориентированный, а потому, что Ruby реализует OO.Этот "класс", который вы определяете там ... это объект.Это объект типа «Класс».Ваш вызов puts считается "макросом класса".Область, в которой он запускается, является экземпляром класса (а не экземпляром Greeter).Поскольку Ruby создает экземпляр определения класса (то есть объект Class), когда он его интерпретирует, ваш оператор запускается сразу во время выполнения.

Было бы неплохо получить копию рубиновой книги кирки (Программирование Ruby1.9), и если вам интересно, как Ruby работает с такими динамическими вещами, вам, возможно, действительно понравится метапрограммирование Ruby.

1 голос
/ 23 февраля 2011

Это задуманная философия дизайна.Это происходит из:

Есть ли лучшее место для реализации и вызова логики определения класса, чем тело класса?!

1 голос
/ 23 февраля 2011

Код внутри определения класса, но вне любого из методов, является очень мощной функцией в Ruby, особенно с учетом его динамической природы.На самом деле это похоже на создание статических конструкторов в других языках.По сути, это предназначено для кода, который должен быть выполнен до того, как методы вашего класса когда-либо будут использованы.Вы можете использовать это, чтобы фактически управлять вашим классом во время выполнения.Посмотрите на такие методы, как attr_accessor, чтобы понять, почему это так полезно.

0 голосов
/ 23 февраля 2011

Другой способ объяснить это:

class Greeter

Вы выполнили оператор класса.Он определяет класс, и вы находитесь внутри этого класса

2:   def say_hello
3:     puts "Hello"
4:   end

Вы выполняете def код внутри класса Greater.Этот код создал метод

6:   puts "Goodbye!"

Вы находитесь внутри класса Greeter, и выполняется другой код (путы).Этот код напечатал GoodBye! в консоли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...