Ruby 中的私有/受保护块?

发布于 2024-07-24 14:01:58 字数 241 浏览 12 评论 0原文

Ruby 似乎没有像这样定义受保护/私有块的功能:

protected do
  def method
  end
end

相比,这会很好

protected 

def method 
end 

public

与您可能忘记在受保护方法之后“公开”的情况

。 似乎可以使用元编程来实现这一点。 有什么想法吗?

Ruby doesn't seem to have a facility for defining a protected/private block like so:

protected do
  def method
  end
end

This would be nice compared to

protected 

def method 
end 

public

where you might forget to "public" after the protected methods.

It seems possible to implement this using metaprogramming. Any ideas how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

残花月 2024-07-31 14:01:58

由于您想按功能进行分组,因此您可以声明所有方法,然后通过使用 protected 后跟要保护的方法的符号来声明哪些方法是受保护的和私有的,对于私有方法也是如此。

下面的课程展示了我的意思。 在这个类中,除了 bar_protected 和 bar_private 之外,所有方法都是公共的,它们最后声明为 protected 和 private。

class Foo

  def bar_public
    print "This is public"
  end

  def bar_protected
    print "This is protected"
  end

  def bar_private
    print "This is private"
  end

  def call_protected
    bar_protected
  end

  def call_private
    bar_private
  end

  protected :bar_protected

  private :bar_private

end

Since you want to group by functionality you can declare all your methods, and then declare which ones are protected and private by using protected followed by the symbols of the methods you want to be protected, and the same for private.

The following class shows what I mean. In this class all methods are public except bar_protected and bar_private which are declared protected and private at the end.

class Foo

  def bar_public
    print "This is public"
  end

  def bar_protected
    print "This is protected"
  end

  def bar_private
    print "This is private"
  end

  def call_protected
    bar_protected
  end

  def call_private
    bar_private
  end

  protected :bar_protected

  private :bar_private

end

我实际上赞同 bodnarbm 的解决方案,并且不建议这样做,但由于我不能放弃元编程挑战,因此这里有一个可以完成此任务的 hack:

class Module
  def with_protected
    alias_if_needed = lambda do |first, second|
      alias_method first, second if instance_methods.include? second
    end
    metaclass = class<<self; self end
    metaclass.module_eval {|m| alias_if_needed[:__with_protected_old__, :method_added]}
    def self.method_added(method)
      protected method
      send :__with_protected_old__ if respond_to? :__with_protected_old__
    end
    yield
    metaclass.module_eval do |m|
      remove_method :method_added
      alias_if_needed[:method_added, :__with_protected_old__]
    end
  end
end

I actually endorse bodnarbm's solution and do not recommend doing this, but since I can't pass up a metaprogramming challenge, here's a hack that will accomplish this:

class Module
  def with_protected
    alias_if_needed = lambda do |first, second|
      alias_method first, second if instance_methods.include? second
    end
    metaclass = class<<self; self end
    metaclass.module_eval {|m| alias_if_needed[:__with_protected_old__, :method_added]}
    def self.method_added(method)
      protected method
      send :__with_protected_old__ if respond_to? :__with_protected_old__
    end
    yield
    metaclass.module_eval do |m|
      remove_method :method_added
      alias_if_needed[:method_added, :__with_protected_old__]
    end
  end
end
兔姬 2024-07-31 14:01:58

老问题,但我认为这更干净一些:

class Whatever

  module ProtectedBits
    protected
      def foo()
        ...
      end
  end

  include ProtectedBits
end

Old question, but I think this is a bit cleaner:

class Whatever

  module ProtectedBits
    protected
      def foo()
        ...
      end
  end

  include ProtectedBits
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文