2015-03-30 4 views
1

Я очень смущен. В «Программе Ruby book» говорится: «приемник проверяет определение метода в своем классе»Вызов метода экземпляра в классе в Ruby

Таким образом, объект класса хранит все методы экземпляра. Тогда почему я не могу вызвать метод экземпляра из класса?

Например

Class ExampleClass 
    def example_method  
    end 
    example_method 
end 

Я не могу назвать example_method внутри ExampleClass.

Однако если определить метод в верхнем уровне, как это:

class ExampleClass 
    def example_method 
    end 
end 

def example_method1 
end 

example_method1 

Тогда я могу назвать метод верхнего уровня example_method1.

Не высший уровень также класс? Почему он отличается от метода вызывающего экземпляра из ExampleClass?

+0

Метод экземпляра должен быть вызван * на экземпляре *. Если у вас его нет, вы должны создать его. Давид имеет здесь верный ответ. – tadman

+0

Чтобы ответить на ваш вопрос о том, почему поведение отличается на верхнем уровне, я рекомендую прочитать [What is the Ruby Top-Level?] (Https://banisterfiend.wordpress.com/2010/11/23/what-is -the-ruby-top-level /) – Ajedi32

+0

@ Ajedi32 Большое вам спасибо за ссылку на статью.Таким образом, верхний уровень действительно «двойной природы» :) – meizin

ответ

3

Основная причина, по которой вы не можете назвать эту функцию так, как вы ее написали, заключается в том, что она, как вы говорите, метод экземпляра.

Попробуйте определив его следующим образом:

Class ExampleClass 
def self.class_method 
    puts "I'm a class method" 
end 
class_method 
end 

Я полагаю, вы обнаружите, что у вас есть другой результат. Дело не в том, что это «верхний уровень», а в том, зависит от того, с чем вы имеете дело. Поскольку вы имеете дело с классом, необходим метод класса. Если вы имеете дело с объектом (экземпляр класса), это другой «масштаб».

+1

'Класс' должен быть' class'. – steenslag

+0

Я понимаю метод класса, определенный с помощью себя. Я не понимаю: внутренне, если метод экземпляра хранится в классе, то почему бы не иметь к ним доступ? – meizin

+0

Как вы сказали: это метод экземпляра. В способе, которым вы его написали, этот метод доступен только в экземпляре ExampleClass: 'ex = ExampleClass.new', а затем вы достигаете метода через' ex.example_method' – Klaus

1

Эти «глобальные» методы являются исключением. Они определяются как частные методы экземпляра объекта. Все наследуется от Object, поэтому эти методы отображаются «глобально».

p self.class # => Object 
p self.private_methods.sort # => [:Array, :Complex, ... :using, :warn] # all (?) from Kernel module 

def aaaa 
end 

p self.private_methods.sort # => [:aaaa, :Array, ... :using, :warn] 
1

Я попытаюсь объяснить это следующим образом.

class MyClass 
    def self.my_method 
    puts "Me, I'm a class method. Note that self = #{self}" 
    end 

    def my_method 
    puts "Me, I'm an instance method. Note that self = #{self}" 
    end 

    # I'm about to invoke :my_method on self. Which one will it be?" 
    # "That depends on what self is now, of course. 

    puts "self = #{self}" 

    # OK. It's MyClass. But wait. I'm just defining the set now. 
    # Do the methods I defined above even exist yet? 
    # Does the class exist yet? Let's find out. 

    print "class methods: " 
    puts self.methods(false) 
    print "instance methods: " 
    puts self.instance_methods(false) 

# Cool! Let's try invoking my_method 

    my_method 

    # It worked. It was the class method because self = MyClass 

    # Now let's see if we can create an instance of the class before 
    # we finish defining the class. Surely we can't. 

    my_instance = new 
    puts "my_instance = #{my_instance}" 

    # We can! Now that's very interesting. Can we invoke the 
    # instance method on that instance? 

    my_instance.my_method 

    # Yes! 
end 

Ниже печатается в то время как класс определяется:

self = MyClass 
class methods: my_method 
instance methods: my_method 
Me, I'm a class method. Note that self = MyClass 
my_instance = #<MyClass:0x007fd6119125a0> 
Me, I'm an instance method. Note that self = #<MyClass:0x007fd6119125a0> 

Теперь давайте подтвердить эти методы могут быть вызваны извне класса. Здесь не должно быть никаких сюрпризов:

MyClass.my_method 
    #-> Me, I'm a class method. Note that self = MyClass 
my_instance = MyClass.new 
my_instance.my_method 
    #-> Me, I'm an instance method. Note that self = #<MyClass:0x007fd61181d668> 
+0

, который вы пишете процедурный код в классе, который находится за пределами любых определений методов? – ahnbizcad

1

Получатель проверяет определение метода в своем классе. Приемник - ExampleClass. Класс ExampleClass - Class. Нет метода example_method в классе Class, эрго, вы получаете NoMethodError.

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