Don't the Ruby methods instance_eval() and send() negate the benefits of private visibility?

后端 未结 5 965
误落风尘
误落风尘 2021-01-21 12:45
w = Widget.new # Create a Widget
w.send :utility_method # Invoke private method!
w.instance_eval { utility_method } # Another way to invoke it
w.instance_eval { @x } # R         


        
5条回答
  •  耶瑟儿~
    2021-01-21 13:25

    I cannot comment, because of low rep :/.

    Redefining send is no use, because send is just the common name for __send__ (thats underscore,underscore,"send",underscore,underscore), which is the method actually implementing message sending. Redefining any __method__ is not recommended. Additionally, the other person can also reopen the class and revert the definition:

    class Widget
      def send(method, *args, &block)
        super
      end
      #and so on
    end
    

    In Ruby 1.9, the behaviour is slightly different: #send actually honors visibility, __send__ doesn't.

    private in Ruby has more of a declarative purpose: methods declared as private are an implementation detail and not an API detail. You are not allowed to send a message from the outside by accident. But anyone can still forcefully circumvent that restriction, if they see fit - on their own account.

提交回复
热议问题