Почему этот метод Ruby должен быть методом уровня класса? - PullRequest
0 голосов
/ 28 февраля 2012

Вот классическое fizzbuzz в Ruby:

class PrimeChecker
  def print_em
    1.upto 100 do |fizzbuzz|
      if (fizzbuzz % 2) == 0 && (fizzbuzz % 5) == 0
        puts "fizzbuzz: " + fizzbuzz.to_s
      elsif (fizzbuzz % 5) == 0
        puts "fizz: "+fizzbuzz.to_s
      elsif (fizzbuzz % 2) == 0
        puts 'buzz: ' + fizzbuzz.to_s
      else
        puts "-" + fizzbuzz.to_s
      end
    end
  end
end
PrimeChecker.print_em

При выполнении этого я получаю эту ошибку:

неопределенный метод 'print_em'.

Я меняю метод на self.print_em, и он работает.Значит ли это, что это метод класса (я так думаю)?Был ли метод "не найден" раньше, потому что я могу вызывать такие методы в классе только на реальных экземплярах объекта?Если бы я хотел, чтобы это был метод экземпляра, каков синтаксис для этого?Я пытаюсь лучше понять Ruby, классы и методы.

Ответы [ 4 ]

5 голосов
/ 28 февраля 2012

Методы класса - это просто: вызывается для класса .Тогда как методы экземпляра вызываются для экземпляра этого класса .Пример более полезен:

class Foo
  def self.bar
    "This is a class method!"
  end

  def bar
    "This is an instance method!"
  end
end

Foo.bar        # => "This is a class method!"
foo = Foo.new  # This creates "foo" to be a new instance of Foo
foo.bar        # => "This is an instance method!"

Обратите внимание, что "методы класса" в Ruby на самом деле являются методами в синглтоне объекта класса.Это довольно сложная концепция для объяснения, и вы можете узнать больше об этом , если хотите.

0 голосов
/ 28 февраля 2012

В: Когда я запускаю ruby.rb, я получаю неопределенный метод print_em.Я изменяю метод на self.print_em, и он работает.Означает ли это, что это метод класса (я так думаю).

A: Да.class Bar; ... def self.foo определяет метод класса foo для класса Bar.

В: Был ли ранее метод "не найден", потому что я могу вызывать такие методы в классе только на реальных экземплярах объекта?

A: Сначала вы определили его как метод экземпляра.В этом случае он доступен только для экземпляров класса.

В: Если я хотел, чтобы это был метод экземпляра, каков синтаксис для этого?

A: То, как вы это делали изначально: class Bar; def foo определяет экземпляр метод foo для класса Bar

0 голосов
/ 28 февраля 2012

Это не метод класса, как написано; вам нужно запустить его с экземпляром PrimeChecker:

pc = PrimeChecker.new
pc.print_em

Использование self. превращает его в метод класса, запускаемый с указанным синтаксисом.

Для не нужно , чтобы быть методом класса, просто вы пытаетесь его выполнить.

0 голосов
/ 28 февраля 2012

Да, вы совершенно правы. В настоящее время способ, которым вы его определяете, вы можете оценить метод с помощью:

PrimeChecker.new.print_em

Причина, по которой def self.my_awesome_method определяет его на стороне класса, заключается в том, что вещи внутри

class MyAwesomeClass
end

выполняется в контексте MyAwesomeClass. Это все код Ruby, как вы можете видеть! Это позволяет вам делать такие вещи:

class MyAwesomeClass
  puts "Hello from innards of #{self}!" #=> Hello from the innards of MyAwesomeClass!
end

Определения методов также будут работать, только если вы называете их после местоположения определения, например:

class MyAwesomeClass
  my_awesome_method   # produces a nasty error
  def self.my_awesome_method
    puts "Hello world"
  end
  my_awesome_method   # executes just fine
end

Надеюсь, это прояснит некоторые вещи.

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