# Protected methods and class methods

**URL:** <https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516>\
**Category:** Ruby\
**Created:** [January 20, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516 "2006-01-20T21:13:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![gioele](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/8491ac/32.png) [@gioele](https://www.ruby-forum.com/u/gioele)\
**Post date:** [January 20, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516/1 "2006-01-20T21:13:05Z")

</div>

Hi,

is there a way to call a protected method of a class from a static  
method of  
the same class? Or to acces an instance variable of a class from a  
static  
method of the same class?

Now I’m facing a problem. I use some static methods as “factory  
methods”, to  
create “prefilled” class instances. These methods can’t access the  
protected  
methods of the same class. Is this behavior intentional? Is there clean  
solution to this problem? If not, how can I work around this problem?  
This is  
a public class, so I don’t want to add other params to initialize.

I get this error

irb(main):032:0\> Info.fromBytes("\010\008")  
NoMethodError: protected method `length=' called for #<Info:0x300c3b70 @length=nil, @typeID=8> from (irb):23:in`fromBytes’

with this class

class Info  
def initialize(typeID)  
@typeID = typeID  
@length = nil  
end

```
attr_reader :typeID

def length
  if @length.nil?
    @length = veryLongMathCalcs()
  end
  return @length
end

def Info.fromBytes(bytes)
  typeID = bytes[0, 1].unpack("c")[0]
  length = bytes[1, 1].unpack("c")[0]

  info = Info.new(typeID)
  info.length = length ## <<< this is the error!

  return info
end

```

protected  
attr\_writer :length

end

---

<div class="post-metadata">

**Author:** ![gioele](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/8491ac/32.png) [@gioele](https://www.ruby-forum.com/u/gioele)\
**Post date:** [January 21, 2006, 2:24am UTC](https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516/2 "2006-01-21T02:24:14Z")

</div>

On Sat, 2006-01-21 at 04:34 +0900, Gioele B. wrote:

> Now I’m facing a problem. I use some static methods as “factory methods”, to  
> create “prefilled” class instances. These methods can’t access the protected  
> methods of the same class. Is this behavior intentional?

I believe so. Because the class Info is itself an instance of Class,  
while the instance is an instance of Info, which is entirely unrelated  
to Class (apart from the common ancestor, Object). So there’s no reason  
for protected instance methods on Info to be available to methods on the  
class itself.

(I think static methods are usually referred to as class methods in  
Ruby. _nothing_ is static here).

Access modifiers can be pretty surprising depending where you’re coming  
from. Check out (if you haven’t already):

[http://www.whytheluckystiff.net/ruby/pickaxe/html/tut\_classes.html#S4](http://www.whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4)

> Is there clean solution to this problem? If not, how can I work around this  
> problem? This is a public class, so I don’t want to add other params  
> to initialize.

> I get this error
> 
> irb(main):032:0\> Info.fromBytes(“\010\008”)  
> NoMethodError: protected method `length=' called for #<Info:0x300c3b70 @length=nil, @typeID=8> from (irb):23:in `fromBytes’
> 
> with this class
> 
> [… snipped …]

Maybe try this workaround. I’ve also changed a few things to be more  
‘Rubyish’, but you can just ignore that if you like 🙂

class Info  
def initialize(type\_id)  
@type\_id = type\_id  
@length = nil  
end

attr\_reader :type\_id

def length  
@length ||= very\_long\_math\_calcs  
end

def Info.from\_bytes(bytes)  
type\_id = bytes[0,1].unpack(“c”)[0]  
len = bytes[1,1].unpack(“c”)[0]

```
info = Info.new(type_id)
info.instance_eval { self.length = len } ## <<< changed!

# or (if you don't care about encapsulation here):
# info.instance_eval { @length = len }

info

```

end

# maybe don’t need this now?

protected  
attr\_writer :length  
end

# Noticed a potential error in your input - \008 isn’t valid octal 🙂

p Info.from\_bytes(“\010\015”)  
#=\> #\<Info:0xb7f7b228 @length=13, @type\_id=8\>

Hope that helps,  
Ross

---

<div class="post-metadata">

**Author:** ![gioele](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/8491ac/32.png) [@gioele](https://www.ruby-forum.com/u/gioele)\
**Post date:** [January 22, 2006, 8:59pm UTC](https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516/3 "2006-01-22T20:59:01Z")

</div>

On Mon, 2006-01-23 at 02:56 +0900, Gioele B. wrote:

> > class itself.  
> > Instead it makes sense to me to be able to use Info protected methods from  
> > Info class methods. I see no need for ‘Class’ methods to be able to use  
> > protected members of an arbitrary class, but this is a particular case! Both  
> > methods are strictly related to Info (and its subclasses, but this is just a  
> > detail).

Yes, I can see the logic in that, and I don’t disagree that it’d  
probably make sense in some respects, but now I’ve become more familiar  
with Ruby I think I probably _would_ find it surprising if protected  
methods worked that way. Things are often more simple (and elegant) than  
you’d imagine I suppose…

> > Maybe try this workaround.
> > 
> > ```
> > info = Info.new(type_id)
> > info.instance_eval { self.length = len } ## <<< changed!
> > 
> > ```
> 
> Yes, it worked fine. Just I’m not so happy when I have to use \*\_eval ☹ I feel  
> like cheating. Anyway it is better to have such a shortcut than not 🙂

Definitely 🙂

---

<div class="post-metadata">

**Author:** ![gioele](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/8491ac/32.png) [@gioele](https://www.ruby-forum.com/u/gioele)\
**Post date:** [January 22, 2006, 6:59pm UTC](https://www.ruby-forum.com/t/protected-methods-and-class-methods/63516/4 "2006-01-22T18:59:39Z")

</div>

On Saturday 21 January 2006 01:46, Ross B. wrote:

> On Sat, 2006-01-21 at 04:34 +0900, Gioele B. wrote:
> 
> > Now I’m facing a problem. I use some static methods as “factory methods”,  
> > to create “prefilled” class instances. These methods can’t access the  
> > protected methods of the same class. Is this behavior intentional?
> 
> I believe so. Because the class Info is itself an instance of Class,  
> while the instance is an instance of Info, which is entirely unrelated  
> to Class (apart from the common ancestor, Object). So there’s no reason  
> for protected instance methods on Info to be available to methods on the  
> class itself.  
> Instead it makes sense to me to be able to use Info protected methods  
> from  
> Info class methods. I see no need for ‘Class’ methods to be able to use  
> protected members of an arbitrary class, but this is a particular case!  
> Both  
> methods are strictly related to Info (and its subclasses, but this is  
> just a  
> detail).

> (I think static methods are usually referred to as class methods in  
> Ruby. _nothing_ is static here).  
> Ah, my C++ heritage 🙂

> Maybe try this workaround.
> 
> ```
> info = Info.new(type_id)
> info.instance_eval { self.length = len } ## <<< changed!
> 
> ```
> 
> Hope that helps,  
> Ross  
> Yes, it worked fine. Just I’m not so happy when I have to use \*\_eval ☹  
> I feel  
> like cheating. Anyway it is better to have such a shortcut than not 🙂
