Как стать автором
Обновить

Комментарии 33

Да… что то в 5 утра ни капли не лезет в голову. Спасибо за статью!
А каково мне писалось? ;)
«Классы в Руби — объекты самого высшего класса..»

То, что ты назвал высшем классом, принято называть метаклассом. Можно ли в руби создать свой метакласс и переопределить в нем метод new? В данном случае можно было бы просто создавать сингелтоны, например.
Переопределить класс Class нельзя, а следовательно и метод new. Но метаклассы создавать можно.
Посмотрите например эти статьи:
whytheluckystiff.net/articles/seeingMetaclassesClearly.html
vision-media.ca/resources/ruby/understanding-ruby-metaclasses
reference.jumpingmonkey.org/programming_languages/ruby/ruby-metaprogramming.html
Извиняюсь, я вас немного дезинформировал:)
Class переопределить нельзя, а вот метод new в нем можно.
Пример из документации:
   class Class
      alias oldNew  new
      def new(*args)
        print "Creating a new ", self.name, "\n"
        oldNew(*args)
      end
    end

    class Name
    end

    n = Name.new
Почитаю статьи вечером. Я имел ввиду конструкцию, с которой я знаком из xotcl — ниже я написал её реализация на псевдо руби, как её я вижу, надеюсь станет понятнее:

# мета класс сингелтон
class Singelton < Class
def new(*args)
if (@instance==nil) @instance = base.new(args);
@instance
end
end

# использование метакласса Singelton
Singelton God
method Hi
puts "Hello, i'm God"
end
end

Теперь God.new - возвращает один и тот же объект
Этот паттерн уже входит в стандартную библиотеку и используется вот так:

class God
  include Singleton
end

God.instance


А метод-синглтон — это совершенно другое. Это личный метод одного-единственного экземпляра, который недоступен во всех остальных экземплярах того же класса:

class Penguin
  def sing
    # ...
  end
end

memphis = Penguin.new
mumble = Penguin.new

def mumble.sing
  fail
end
def mumble.dance
  # ...
end

memphis.sing
mumble.sing  #  => RuntimeError

mumble.dance
memphis.dance  # => NoMethodError
«return @length»
в данном случае return не нужен.
и вы уверены что super надо вызвать не в самом начале конструктора?
Все-таки правильно сказанно в статье, что initialize по настоящему конструктором не является. Конструктор — это метод new который выделяет память и создает объект, а затем вызывает метод initialize. initialize можно рассматривать как просто метод инициализации(что и отражено в его названии:)).
А super в теле метода означает что мы просто вызываем аналогичный метод суперкласса, его можно использовать в любом методе, не только в initialize.
Именно по этому мы не обязаны вызыват super в самом начале initialize, как в Java например.
	def initialize(name, age)
		@name = name
		@age = age
		super
	end 

Хм, а если так, то почему такая конструкция не «обнилит» переменные? Ведь super вызывается без параметров, а значит (я так думаю :) ), что инициализатор базового класса Pet получит в своих парметрах nil и обнилит переменные. Просто проверить сейчас не могу

Если мы вызываем super без параметров, то ему автоматически придут те же параметры что и методу, его вызывающему.
Т.е. в данном случае вызов super аналогичен вызову super name, age, а не super nil, nil
Ну а вообще, да, пример какой-то странный:) Потому что, как вы правильно заметели — переменные затераються:
class Dog
	def initialize(name, age)
		@name = name+"  - dog"
		@age = age
		super
	end 
end
dog = Dog.new "Rex", 5
<pre>
В результате @name будет равно "Rex" а не "Rex - dog", потому как  Pet.initialize вызывается со значением "Rex".
и здесь тоже

def initialize(name, age, length)
@name = name
@age = age
@length = length
super(name, age)
end
> Конструктор — это метод new который выделяет память и создает объект, а затем вызывает метод initialize

Конструктор — это allocate (можно его вызвать при создании, без инициализации), а new — всего лишь обертка для allocate + initialize

class A
  def initialize
    p self
  end
end

a = A.new
b = A.allocate # создаст объект, но без init'a
>Им обозначаются переменные, которые классы-потомки должны передать вышестоящему классу. Просто super передаст все переменные, super() — ни одной.

Вот что-то не допер, что вообще значит «передать вышестоящему классу», вызвать его конструктор (который инициализатор) с этими переменными или что-то другое?
уже допер по ответу выше :)
откуда вы эти get_, set_ взяли? не пишут так в ruby.
«Настоящий программист может написать фортрановскую программу на любом языке».
закатайте потом все капли в пдф, в колонтитул поместите ссылку, допустим, на свой блог и пустите в свободное плавание. Многие спасибо вам скажут
А смысл? Получиться тот же викибукс про Ruby, только в pdf. Тут основной плюс что в коментариях подсказать могут.
Спасибо, интересно.

Было бы здорово выпустить еще теоретическую часть, меня например, очень интересуют особенности реализации ООП в Ruby. Очень было бы познавательно почитать сравнительную статью о, например, Java — Ruby с точки зрения реализации ООП. Может где-то есть такая статья? Не раскрыты темы интерфейсов, множественного наследования, области видимости и тд.

Я для себя открываю тут Ruby благодаря вашим статьям ) и вижу, что возможно это хорошая альтернатива Java для небольших проектов.
Насчет Ruby для Java программистов.
Можете на оф. сайте глянуть:
www.ruby-lang.org/en/documentation/ruby-from-other-languages/
Или эту книжку:
www.flazx.com/ebook5807.php
>возможно это хорошая альтернатива Java для небольших проектов.
Очень хорошая, например, потому что еще есть JRuby:)
jruby.codehaus.org/
Кстати, в Руби используется ООП модель Смаллталка — объекты не вызывают методы, а посылают сигналы.
Извините, конечно, я руби не знаю. Может все так и есть, но ИМХО фраза:

«Классы в Руби — объекты самого высшего класса, каждый из них является экземпляром встроенного в Руби класса Class (тавтология, но понять нужно). Когда определяется новый класс (обычно используя class Name… end), создается объект типа Class.
»

некорректная. И звучать должно примерно так:

Класс в Руби является потомком встроенного в класса Class. Когда определяется новый класс, он автоматически становится наследником типа Class.

Или я чего то не понял?

НЛО прилетело и опубликовало эту надпись здесь
Нет. В руби есть такая мантра для запоминания:
Class — это объект, а Object — это класс. :)
Новый класс становится наследником встроенного класса Object, при этом сам новый класс (не экземпляры этого класса, а сам класс, как тип) является экземпляром класса Class.
А, там еще и Object есть. Тогда понятно.
Что за ужас get_name и set_name? :( В Руби принят о так:
class Dog
def name
@name
end
def name=(str)
@name = str
end
end
Я бы даже сказал, что так:
class Dog
  attr_accessor :name
end
> Я бы даже сказал, что так:

только в случае примитивного аксессора
Ну я говорил о примерах из статьи :)
А так всё верно, только в случае примитивного
Прикольная серия статей.
по-поводу девятой капли (надеюсь будет:)
Очень полезным считаю нераскрытую тему case-when в руби, операторы ===, <=>, примеси (mixin), отдельно даже полезно рассмотреть примешивание Enumerable.
Верю в Вас и в будущие капли.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации