2015-09-16 4 views
1

При создании класса, мы используем ключевое слово class как:В чем разница между `` Class` и class`

class Abc 
    Z = 5 
    def add 
    puts "anything here" 
    end 
end 

В консоли Abc.class # => Class

Как Abc внутренне стать классом? В чем разница между class и Class?

Было бы здорово, если бы кто-нибудь мог объяснить, как внутренние константы и метод внутренне вызываются, а если метод не определен, то как мы получаем исключение "undefined class method". Какова внутренняя логика этого?

ответ

1

Чтобы посмотреть, что отличное "class" вещи в Ruby mean, выезд my other answer.


А как методы ищутся:

Есть несколько мест метод может исходить от:

  1. Класс объекта
  2. Родитель класса объект
  3. Модули, которые включены/добавлены
  4. Одноэлементный класс объекта

Порядок поиска заключается в следующем:

  1. Если он существует, то синглтон класс
  2. предваряется модули
  3. методы, определенные в классе
  4. Включенные модули
  5. Рекурсивный, вышеуказанные правила для родительского класса

Есть несколько вещей, которые нужно отметить здесь:

  1. Если несколько модулей включены/предваряется, они будут просматриваться в обратном порядке, как они были включены/предваряется
  2. Если модуль был уже включен/добавлен в один из партентов, он не будет включен/добавлен снова
  3. Если использовать эти правила, метод не был найден до самого начала иерархии (BasicObject), цепочку предков снова ищут для другой метод, который называется method_missing
  4. BasicObject#method_missing определяется так, что он бросает NoMethodError и где ошибка происходит от

module M1 
    def foo 
    puts 'Defined in M1' 
    end 
end 

module M2 
    def foo 
    puts 'Defined in M2' 
    end 
end 

class C 
    include M1 
    prepend M2 

    def foo 
    puts 'Defined in C' 
    end 

    def method_missing(method_name) 
    puts 'Method missing' if method_name == :foo 
    end 
end 

c = C.new 

# singleton method 
def c.foo 
    puts "Defined in c's singleton" 
end 

puts c.singleton_class.ancestors 
    # => [#<Class:#<C:0xa2d0f8>>, M2, C, M1, Object, Kernel, BasicObject] 
    # ^the singleton class, 
    #  the prepended module, 
    #  the C class itself, 
    #  the included module, 
    #  the rest of the hierarchy 
    # (Object is the implicit parent of all classes with no explicit parent) 
+0

Большое вам спасибо за ваши прекрасные объяснения. – Chitra

1

с class Abc вы определяете класс.

Abc.class возвращается тип, и тип Abc является Class

другой пример:

1337.class 
=> Fixnum 
"hi babe!".class 
=> String 
12.55.class 
=> Float 
(1..12).class 
=> Range 

так, как вы можете видеть, каждый «тип данных» является классом. в вашем случае Abc также является типом данных. И для конца этой цепочки класс класса - это класс! :-)

+0

'# class' возвращает класс объекта, нет четкой концепции«типа»в Ruby. – Borsunho

+0

Я просто использовал слово «тип/тип данных», так как у вас есть все типы типов данных на других языках, где эти типы данных, в то время как они являются классами в рубине. –

+1

Точка, Ruby «утиная», и поэтому самый близкий эквивалент объекта 'type' - это одноэлементный класс или набор методов, ни один из которых не возвращается '# class'. – Borsunho

14

Есть три разных вещей здесь:

  1. class это ключевое слово, которое используется для определения или возобновлять класс
  2. Object#class является метод, который возвращает класс данного объекта
  3. Class это класс, который все классы экземпляр (включая Class себя)
+0

Вы объясните это очень хорошо, но было бы неплохо, если бы вы могли объяснить мне внутреннюю работу от создания класса до вызова его метода. – Chitra

+0

@Chitra, вы имеете в виду, как 'bar' будет найден, когда вы вызываете' foo.bar'? Или как Ruby хранит классы? – ndn

+0

Да, и еще один вопрос здесь, как если бы мы вызывали метод с экземпляром класса, и этот метод не объявлялся внутри класса, откуда мы получили это исключение «NoMethodError:», как оно вызывается, и есть ли способ переопределить существующий метод класса и создать пользовательский метод времени выполнения. так что мы не сможем снова получить это исключение «NoMethodError:». – Chitra

2

ndn's answer дает хороший обзор различных вещей, на которые может ссылаться «класс».

Чтобы ответить на ваш конкретный вопрос:

How does Abc internally become a class?

Почти как и любой другой объект.

class Abc 
end 

эквивалентно:

Abc = Class.new do 
end 

Он создает новый экземпляр Class и присваивает его постоянной Abc.

0

Ответ на второй вопрос, undefined class method происходит, когда метод, который вы назвали, отсутствует в таком классе - классы - это просто объекты в Ruby, и поэтому они имеют свой собственный набор методов.Рубин имеет несколько способов определить методы класса, наиболее распространенным является, вероятно,

class Klass 
    def self.klass_method 
    ... 
    end 
end 

другого

class Klass 
    # some ordinary instance methods here 
    class << self 
    def klass_method 
     # this is class method 
    end 
    end 
end 

Некоторых Рубисты предпочитают последние, так как он сохраняет все методы класса в одном блоке, но они эквивалентны ,

Смежные вопросы