# How to control self.method access

**URL:** <https://www.ruby-forum.com/t/how-to-control-self-method-access/126295>\
**Category:** Rails\
**Created:** [January 17, 2008, 4:42am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295 "2008-01-17T04:42:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 17, 2008, 4:42am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/1 "2008-01-17T04:42:34Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 17, 2008, 8:12am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/2 "2008-01-17T08:12:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 17, 2008, 9:09am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/3 "2008-01-17T09:09:20Z")

</div>

## 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 method`say\_hello’ called for Foo:Class  
(NoMethodError)’

why this happen?

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 17, 2008, 5:16pm UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/4 "2008-01-17T17:16:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 18, 2008, 8:12am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/5 "2008-01-18T08:12:57Z")

</div>

## 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 method`say\_hello’ called for Test:Class  
(NoMethodError)  
How should I do can both make class methods are private and can be  
invoked

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 18, 2008, 8:52pm UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/6 "2008-01-18T20:52:48Z")

</div>

> private\_class\_method :say\_hello  
> end
> 
> ## Test.new.say
> 
> run above code will get follow error message  
> Test.rb:4:in `say': private method`say\_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

---

<div class="post-metadata">

**Author:** ![vincent](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/e9bcb4/32.png) [@vincent](https://www.ruby-forum.com/u/vincent)\
**Post date:** [January 19, 2008, 9:35am UTC](https://www.ruby-forum.com/t/how-to-control-self-method-access/126295/7 "2008-01-19T09:35:47Z")

</div>

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?
