Skip to content

Instantly share code, notes, and snippets.

@rentalcustard
Created October 30, 2012 08:43
Show Gist options
  • Save rentalcustard/3979048 to your computer and use it in GitHub Desktop.
Save rentalcustard/3979048 to your computer and use it in GitHub Desktop.
Ruby private methods
class PrivacyExample
def some_public_method
self.some_private_method
end
def some_private_method
"o hai"
end
private :some_private_method
end
#> PrivacyExample.new.some_public_method
#NoMethodError: private method `some_private_method' called for #<PrivacyExample:0x007f98c48f4800>
# from (irb):3:in `some_public_method'
# from (irb):12
# from /Users/tomstuart/.rvm/rubies/ruby-1.9.2-p320/bin/irb:16:in `<main>'
class PrivacyExample
def some_public_method
some_private_method
end
def some_private_method
"o hai"
end
private :some_private_method
end
#> PrivacyExample.new.some_public_method
# => "o hai"
#of course, setters are completely different...
class PrivacyExample
def some_var=(some_val)
@some_var = some_val
end
private :some_var=
def some_public_method
some_var = "foo"
@some_var
end
end
#1.9.2p320 :011 > PrivacyExample.new.some_public_method
# => nil
#some_var in some_public_method shadows the setter, so @some_var is still nil.
class PrivacyExample
def some_var=(some_val)
@some_var = some_val
end
private :some_var=
def some_public_method
#should fail - calling a private method with explicit receiver.
self.some_var = "foo"
@some_var
end
end
#1.9.2p320 :018 > PrivacyExample.new.some_public_method
# => "foo"
#wat.
@rentalcustard
Copy link
Author

@matthewrudy I'm completely fine with local variables shadowing private methods. That's sensible. The 'wat' is a) private methods can't be called with an explicit receiver, even if that receiver is self (I can't think of any reason I'd want this behaviour, as opposed to @urbanautomaton's suggestion); and b) if your private method is a setter and you call it with an explicit receiver of self, it works.

It's not even like there's an underlying technical reason for this wat-inducing behaviour; the protected keyword works exactly as @urbanautomaton describes.

@alloy
Copy link

alloy commented Oct 30, 2012

In this case you can work around it by making the method protected instead of private.

@alloy
Copy link

alloy commented Oct 30, 2012

@mortice And you apparently commented just before me about it :)

@rentalcustard
Copy link
Author

@alloy yea - absolutely. What I don't understand is why Ruby would provide a keyword with protecteds (useful) behaviour, and then one like private, for which I can see no use whatsoever and which doesn't even work consistently when you consider setters. It's just... wat.

@rentalcustard
Copy link
Author

it's ok guys i have a fix

class Module
  def private(*args)
    protected(*args)
  end
end

@rentalcustard
Copy link
Author

Although actually that's no good either, because protected allows you to call the method from any instance of the defining class (or, I think, any instance of an object that includes the defining module). Which is something additional to private. So yea.

lolruby.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment