2011-11-05 61 views
4

当在一个Ruby类定义中声明private/protected时实际发生了什么?它们不是keywords,所以这意味着它们必须是方法调用,但我无法找到它们被定义的位置。他们似乎没有记录。两种不同的方式声明private/protected方法(如下所示)的实现方式不同吗? (第二种方法显然是一个方法调用,但这不是在第一种方式如此明显。)在Ruby中声明“private”/“protected”时实际发生了什么?

class Foo 
    private 
    def i_am_private; end 
    def so_am_i; end 
end 

class Foo 
    def i_am_private; end 
    def so_am_i; end 
    private :i_am_private, :so_am_i 
end 
+1

你看过http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Private? – jtbandes

+0

是的,但是这并没有说明方法在哪里或如何实际执行。我完全知道什么是'private'&'protected',我对Ruby的内部(* how *&* where *)很好奇。 –

回答

9

两者都是方法调用。从docs引用:

每个函数都可以以两种不同的方式使用。

  1. 如果在没有参数的情况下使用,则三个函数设置后续定义的方法的默认访问控制。
  2. 使用参数,函数设置命名方法和常量的访问控制。

查看文档在这里:

  1. Module.private
  2. Access Control

你要找的Module.private方法是如何开始存在。 Here is where that happens。关于它的here is some more information。您需要详细阅读,从class.c中定义的rb_define_private_method开始。

希望有帮助!

+0

我很好奇为什么这里不显示:http://www.ruby-doc.org/core-1.9.2/Module.html –

+0

我同意它应该在那里,但我不知道为什么不是。我不太喜欢这些文档 - 它可能会有很大的改进! – Zabba

+0

您是否知道该方法实际定义的位置?这是我真正想要的一部分。我想它可能在'class.c'中,但我似乎无法找到它。 –

0

我想补充一些有关自己关键字样行为,因为答案已经比较了解其中如何;答案在于Ruby的复杂元编程功能。 有可能使用它们作为关键字使用method_added钩子; Ruby中的一个钩子是一个在特定事件(即钩子名称)发生时被调用的函数。 重要的是,method_added挂钩接收已定义方法的名称作为其参数:这样,可以修改它的行为。例如,你可以使用这个钩子来定义类似于Python的装饰器的行为;重要的部分是,不同于privateprotected方法,这个装饰类的方法应该定义一个method_added即取消定义本身:

class Module 
    def simple_decorator 
    eigenclass = class << self; self; end 
    eigenclass.class_eval do 
     define_method :method_added do |name| 
     eigenclass.class_eval { remove_method :method_added } 
     old_name = 'old_' + name.to_s 
     alias_method old_name, name 
     class_eval %Q{ 
      def #{name}(*args, &block) 
      p 'Do something before call...' 
      #{old_name}(*args, &block) 
      p '... and something after call.' 
      end 
     } 
     end 
    end 
    end 
end 

class UsefulClass 
    simple_decorator 
    def print_something 
    p "I'm a decorated method :)" 
    end 

    def print_something_else 
    p "I'm not decorated :(" 
    end 
end 

a = UsefulClass.new 
a.print_something 
a.print_something_else 

simple_decorator看起来像一个语言的关键字,并且表现得像private;但是,因为它删除了method_added钩子,它仅适用于紧随其后的方法定义。

+0

我怜悯那些不得不维护这样的代码的可怜人。只因为你可以,并不意味着你应该。 – mastaBlasta

相关问题