Tuesday, November 28, 2006

Ruby: Protected class methods

Given the following class subjects_xml and subjects_html are public, not protected.
class Blog
def self.available_subjects(format)
case format
when :xml then subjects_xml
when :html then subjects_html
end
end

protected
def self.subjects_xml
[xml implementation]
end

def self.subjects_html
[html implementation]
end
end
The def self. code can be thought of as defining a class method of Blog, but it is actually defining a method on self, where self is the virtual class of Blog. The protected visibility modifier is being used to specify the visibility of the methods of Blog. Since the subjects_xml and subjects_html methods are being defined on self (the virtual class of Blog) the protected visibility is not applied.

It is possible to define protected class methods in various ways.
class Blog
class << self
def available_subjects(format)
case format
when :xml then subjects_xml
when :html then subjects_html
end
end

protected
def subjects_xml
[xml implementation]
end

def subjects_html
[html implementation]
end
end
end

class Blog
def self.available_subjects(format)
case format
when :xml then subjects_xml
when :html then subjects_html
end
end

def self.subjects_xml
[xml implementation]
end

def self.subjects_html
[html implementation]
end

class<<self;self;end.send :protected, :subjects_xml, :subjects_html
end

5 comments:

  1. What's a compelling reason to do this?

    ReplyDelete
  2. To use a visibility modifier? I'm not going to attempt that answer in a comment. =)

    Hopefully someone has some information they can link to.

    ReplyDelete
  3. chris roos9:52 AM

    Really pedantic (sorry), but why:

    class << self;self;end.send :protected, :subjects_xml, :subjects_html

    rather than:

    class << self
    protected :subjects_xml, :subjects_html
    end

    The second one just looks a little cleaner to me.

    ReplyDelete
  4. There are a few ways to do it, I just threw two examples up there...

    ReplyDelete
  5. Hey Jay,

    You do know that because of the way Ruby inheritance is structured that protected doesn't really make sense for class methods.

    As matz explains here

    ReplyDelete

Note: Only a member of this blog may post a comment.