Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby class with static method calling a private method?

I have a class with a number of static methods. Each one has to call a common method, but I'm trying not to expose this latter method. Making it private would only allow access from an own instance of the class? Protected does not seem like it would solve the problem here either.

How do I hide do_calc from being called externally in a static context? (Leaving it available to be called from the first two static methods.)

class Foo   def self.bar     do_calc()   end   def self.baz     do_calc()   end   def self.do_calc   end end 
like image 208
yamori Avatar asked Apr 20 '15 00:04

yamori


People also ask

Can static method call private method?

So yes, it can access any public, protected, and private variable in the class.

How do you call a private method from a class in Ruby?

You need to use "private_class_method" as in the following example. I don't see a way to get around this. The documentation says that you cannot specify the receive of a private method. Also you can only access a private method from the same instance.

Can a class method call a private method?

You can only use private methods with: This means you can't call private methods from outside the class that defines them. Because that would require an “explicit receiver”.

How do you use a private method in Ruby?

Methods that have private visibility implement the internal logic of the object. They can be called inside the same class in which they are defined, or inside derived classes. Unlike protected methods, you can call them only for a current instance of the class (you can't explicitly specify the method receiver).


1 Answers

First off, static is not really part of the Ruby jargon.

Let's take a simple example:

class Bar   def self.foo   end end 

It defines the method foo on an explicit object, self, which in that scope returns the containing class Bar. Yes, it can be defined a class method, but static does not really make sense in Ruby.

Then private would not work, because defining a method on an explicit object (e.g. def self.foo) bypasses the access qualifiers and makes the method public.

What you can do, is to use the class << self syntax to open the metaclass of the containing class, and define the methods there as instance methods:

class Foo   class << self      def bar       do_calc     end      def baz       do_calc     end      private      def do_calc       puts "calculating..."     end   end end 

This will give you what you need:

Foo.bar calculating...  Foo.baz calculating...  Foo.do_calc NoMethodError: private method `do_calc' called for Foo:Class 
like image 118
tompave Avatar answered Sep 22 '22 00:09

tompave