Reputation: 41236
Coming from a long history of C-style syntax and now trying to learn Ruby (on Rails), I've been having my share of issues with its idioms and such, but today I hit one I didn't expect to have a problem with and I can't see whatever it is that must be right in front of my face.
I have a Binary class that includes a private method to derive a URI value from a path value (uri and path are attributes of the class). I'm calling self.get_uri_from_path()
from within Binary.upload()
, but I get:
Attempt to call private method
A snippet of the model looks like this:
class Binary < ActiveRecord::Base
has_one :image
def upload( uploaded_file, save = false )
save_as = File.join( self.get_bin_root(), '_tmp', uploaded_file.original_path )
# write the file to a temporary directory
# set a few object properties
self.path = save_as.sub( Rails.root.to_s + '/', '' )
self.uri = self.get_uri_from_path()
end
private
def get_uri_from_path
return self.path.sub( 'public', '' )
end
end
Am I making the call incorrectly? Am I missing something else that's even more fundamental? The only place that Binary.get_uri_from_path()
is being called from - at the moment - is Binary.upload()
. I'd expect to be able to call a private method from within the same class unless Ruby does something markedly different from other languages I've used.
Thanks.
Upvotes: 23
Views: 16864
Reputation: 3921
there is a heck though where you can call private method in any situation, that being:
object.send(:private_method)
I believe 1.9 has a different implementation of this trick
Upvotes: 1
Reputation: 14086
I believe that the proper idiom in this case is not self.get_uri_from_path() but rather simply get_uri_from_path(). The self is redundant. Further notes: * self.path calls the path method on self, which is presumably defined in the parent class. If you had wanted to access the instance variable directly, you could have said @path. (@ is the sigil for instance variables.) * Parentheses for method arguments are optional except where their absence would cause ambiguity. You could, if you chose, replace get_uri_from_path() with get_uri_from_path. This stands in contrast to Javascript, where a function with no parens represents that function as a value rather than an application of that function.
Upvotes: 1
Reputation: 66436
Don't do
self.get_uri_from_path()
do
get_uri_from_path()
Because...
class AccessPrivate
def a
end
private :a # a is private method
def accessing_private
a # sure!
self.a # nope! private methods cannot be called with an explicit receiver at all, even if that receiver is "self"
other_object.a # nope, a is private, you can't get it (but if it was protected, you could!)
end
end
Upvotes: 46