How to control self.method access

i think self.method just like class method,so if i want to define it
as a private method,i should use

private_class_method :my_method

but i found follow code in < >

private
def self.hash_password(password)
Digest::SHA1.hexdigest(password)
end

just a mistake or there have some thing which i cannot get?

I’ve never used private_class_method but based on the Ruby API it
should do what you want. The agile example will work too, and is
probably a bit more convenient if you have more than one private
method because the private declaration applies to everything that
comes after it.

I always group my class methods in a “class << self” block and then
put private class methods at the end of that block like this:

class Foo
class << self
def some_public_class_method

end

private
def some_private_class_method
  ...
end

end
end

Aaron

but I test follow code

class Foo
private
def self.say_hello
p ‘Hello’
end
end

class Bar
def say
Foo::say_hello
end
end

Bar.new.say

it’s works and puts ‘Hello’,private in class Foo seems useless
i try re-test it use private_class_method and get
‘Test.rb:11:in say': private methodsay_hello’ called for Foo:Class
(NoMethodError)’

why this happen?

I ran your test code and was surprised to see that the private
declaration didn’t apply to the class method. I guess private only
applies to instance methods. So that leaves “private_class_method”
and a “class << self” block as the two ways to make class methods
private.

Aaron

so, the demo code in <> was wrong?
I hava another question,If i keep class methods private via
private_class_method method,I can not invoke these methods
see this

class Test

def say
Test::say_hello
end

def self.say_hello
p ‘Hello’
end

private_class_method :say_hello
end

Test.new.say

run above code will get follow error message
Test.rb:4:in say': private methodsay_hello’ called for Test:Class
(NoMethodError)
How should I do can both make class methods are private and can be
invoked

private_class_method :say_hello
end

Test.new.say

run above code will get follow error message
Test.rb:4:in say': private methodsay_hello’ called for Test:Class
(NoMethodError)
How should I do can both make class methods are private and can be
invoked

You can’t access the private class method from an object instance
because they are in different classes. Every ruby object has what is
called a singleton class that contains per-object attributes. See
Chapter 24 “Classes and Objects” in the Pickaxe book for a much more
thorough explanation.

I took your example above and modified it slightly to show you one
possible way to make it work:

class Test
class << self
def say_hello_accessor
say_hello
end

private
def say_hello
  p 'Hello'
end

end

def say
self.class.say_hello_accessor
end
end

Test.new.say

Hope this helps.

Aaron

Thanks Aaron! It works.But I feel this way put some additional
complexity into Test class. if there have any way can define a private
class method and invoke it directly, that would be nice!
you said:‘You can’t access the private class method from an object
instance,because they are in different classes’.you mean every
instance have an own class and each of them are different,that’s the
reason I can not invoke private class method in instance method,am i
right?