Is There a Difference Between :: and . When Calling Class Methods in Ruby

Is there a difference between :: and . when calling class methods in Ruby?

The . operator basically says "send this message to the object". In your example it is calling that particular member. The :: operator "drills down" to the scope defined to the left of the operator, and then calls the member defined on the right side of operator.

When you use :: you have to be referencing members that are defined. When using . you are simply sending a message to the object. Because that message could be anything, auto-completion does not work for . while it does for ::.

Ruby: Calling class method from instance

Rather than referring to the literal name of the class, inside an instance method you can just call self.class.whatever.

class Foo
def self.some_class_method
puts self
end

def some_instance_method
self.class.some_class_method
end
end

print "Class method: "
Foo.some_class_method

print "Instance method: "
Foo.new.some_instance_method

Outputs:


Class method: Foo
Instance method: Foo

How does ruby tell the difference between instance method and class method definition?

In a method body, self refers to the receiver. In lines 3..4 of the following, once the receiver is determined to be a User instance (by the def greeting syntax), self refers to that instance.

class User
def greeting
puts "Hi, #{name}" # method body
puts "Hi, #{self.name}" # method body
end
end

In a class body, self refers to the class. In lines 2, 4, 8, 10 of the following, the class is User, so def self.greeting is the same as def User.greeting.

class User
def self.greeting # class body
# ...
end # class body
end

class User
def greeting # class body
# ...
end # class body
end

But I actually think your real issue is not what self means, but rather what "an omitted receiver" means, in different contexts.

In method-calling syntax, an omitted receiver stands for self. So the following two are the same:

name
self.name

In method-defining syntax, an omitted receiver stands for "any instance of the class". So the following two are not the same:

def User.greeting; ... end
def greeting; ... end

When you define an instance method, there is no explicit way to express "any instance of the class", so actually omission is mandatory.

What are the practical differences between a module method and a class method in Ruby?

tl;dr: There are no class methods and module methods in Ruby, only instance methods. Considering that they are both just instance methods, and thus the same thing, there cannot possibly be any difference.


There is no such thing as a "class method" or a "module method" in Ruby. Ruby has exactly one kind of method: instance methods.

We sometimes use the word "class method" or "module method" out of convenience when talking about a certain pattern of using instance methods, but there is no such concept in Ruby. "Class methods" and "module methods" are really just singleton methods of an object which just happens to be an instance of the Module class or the Class class. There is absolutely no difference whatsoever between a singleton method of an object which happens to be an instance of Class, Module, String, Array, Hash, Object, Foo, Bar, Whatever, or Garbledigookidoo.

Oh. Did I mention? Singleton methods don't exist, either. Again, it is a word we use for certain kinds of usages of methods, but they are really just regular boring old instance methods of the singleton class of an object.

However, "instance method of the singleton class of foo" and "instance method of the singleton class of Foo, where Foo is an instance of Class" are really long, and so we shorten them to "singleton method of foo" and "class method of Foo" out of convenience, knowing full well that those are fictions that don't actually exist in the language.

Unlike Java, which has three different kinds of methods (instance methods, static methods, and constructors (which are kinda-sorta like methods)), Ruby has exactly one kind of method: instance methods. No class methods, no module methods, no global methods, no top-level methods, no static methods, no constructors. It does, however, have three kinds of classes: regular classes, singleton classes, and include classes (the latter being classes that get synthesized and injected into the inheritance hierarchy when you call include or prepend). These classes differ mainly in whether methods like Object#class, Class#superclass, and Class#ancestors display them or suppress them. Singleton classes are suppressed by all of them, include classes by the first two, but shown by ancestors.

Ruby on Rails instance vs class methods

To define a class method, use the self keyword in the method's definition (or the class' name):

class Notifier
def self.this_is_a_class_method
end

def Notifier.this_a_class_method_too
end

def this_is_an_instance_method
end
end

In your case, reminder_to_unconfirmed_user should be defined as a class method:

class Notifier 

def self.reminder_to_unconfirmed_user(user)
# ...
end

end

Then you can use it like this:

Notifier.reminder_to_unconfirmed_user(User.last)

Is there any difference between Ruby class method calling with in class method with and without self?

Yes, there is a difference. But not in your example. But if foo was a private class method, then your first version would raise an exception, because you call foo with an explicit receiver:

class Test
def self.foo
puts 'Welcome to ruby'
end
private_class_method :foo

def self.bar
self.foo
end
end

Test.bar
#=> NoMethodError: private method `foo' called for Test:Class

But the second version would still work:

class Test
def self.foo
puts 'Welcome to ruby'
end
private_class_method :foo

def self.bar
foo
end
end

Test.bar
#=> "Welcome to ruby"

Difference between . and #

The hash format (Class#method) is not valid ruby, but is used in documentation to describe an instance method.

Class methods are typically documented using a double-colon (Class::method).

You will see examples of both in the ruby docs (e.g. http://www.ruby-doc.org/core-1.9.3/String.html)

The dot format is used in code when actually calling a class method (Class.method), though I have seen some people (unfortunately) use it interchangeably with either the double-colon or hash in documentation.

Call a method in a class in another class in Ruby

From your description this seems to be what you're going for:

class ClassB
def initialize
@instance_of_class_a = ClassA.new
end

def method_calls_method
@instance_of_class_a.method
end
end

Or to pass in the ClassA instance (this is called dependency injection):

class ClassB
def initialize(class_a_instance)
@instance_of_class_a = class_a_instance
end

def method_calls_method
@instance_of_class_a.method
end
end

instance_a = ClassA.new
instance_b = ClassB.new(instance_a)
puts instance_b.method_calls_method

Use or misuse of private class methods in Ruby

There is no such thing as a "class method" in Ruby. There are only instance methods. "Class methods" are actually singleton methods (on an object which just so happens to be an instance of Class), and "singleton methods" are just instance methods of the singleton class.

private methods can only be called with an implicit receiver (which is self), i.e. they can only be called by other methods on the same object (which in turn means they must be methods of the same class or one of its ancestors, i.e. superclasses, prepended modules or included modules).

This means that private "class methods" can only be called by other "class methods", i.e. methods defined in Example's singleton class, Class, Module, Object, Kernel, or BasicObject. You cannot call them from methods defined in Example.

Think about it: what's the purpose of private? Its purpose is encapsulation, we want to encapsulate the internal implementation and representation details from the external protocol. There are two kinds of encapsulation in wide use currently: Abstract Data Type-Oriented Encapsulation (where instances of different types are encapsulated from each other, but instances of the same type can access each other's internals, e.g. classes in Java) and Object-Oriented Encapsulation (where different objects are encapsulated from each other, even if they are instances of the same type, e.g. Ruby and interfaces in Java). Ruby is an object-oriented language, therefore it uses object-oriented encapsulation. (Java OTOH uses ADT-oriented encapsulation for classes, which is counter-intuitive, since it is usually claimed to be an object-oriented language).

In your case, we have two objects, Example and an instance of Example. They are two different objects, so object-oriented encapsulation simply forbids you from accessing one object's private parts from the other object. Even if Ruby did use ADT-oriented encapsulation, it still wouldn't work: ADT-oriented encapsulation allows two instances of the same type to access each other's privates, but the two objects aren't of the same type, one is an instance of Class and the other is an instance of Example.

Basically, you want to manipulate two object's internals at the same time and that is just not possible in OOP. It's a fundamental design principle of OOP that each object (and each object alone) is responsible for its private parts, and you can only interact with that object by sending it messages through its public protocol.

tl;dr: what you want goes directly against the basic encapsulation principles in OO. Either Example::g must be public or you need to change your design. (Resorting to reflective hacks to circumvent access protection in code you have no control over is a code smell at best. Resorting to reflective hacks to circumvent access protection in code you own is just plain wrong, because you control the access protection, you could just change it.)


One possible solution is to leave OOP behind altogether, and look to functional programming for help. We could try and use closures for encapsulation:

We start out with your original example:

class Example
private_class_method def self.g
puts 4711
end

def f
self.class.send(:g)
end
end

Example.new.f
# 4711

Now, we turn g into a local variable and assign a lambda to it, and in turn use that lambda to define f:

class Example
g = -> {
puts 4711
}

define_method(:f, &g)
end

Example.new.f
# 4711

Now, g is (in some sense) even more "private" than before, because it only exists within the lexical scope of the class body, not even class methods defined in a different class body can access it. However, the lambda being referenced by g is a proper object and can be passed around even into different scopes.

But, presumably you don't want f and g to be just identical (otherwise you could just have used module_function, after all), instead you want f to do something other than just delegate to g. That is also possible:

class Example
g = -> {
puts 4711
}

define_method(:f) do
puts 42
g.()
end
end

Example.new.f
# 42
# 4711

This works, because in some other sense g is less "private" than before: lexical scopes can nest, in particular the lexical scopes of blocks (and only blocks) nest, so that the nested block (the block passed to define_method in this case) can access the lexical environment of the outer lexical scope (the class body in this case) even after that lexical scope no longer exists (the class body has finished evaluating).

difference between class method , instance method , instance variable , class variable?

First take a look at this diagram:

from "Metaprogramming Ruby" book

You can rightly say that “obj has a method called my_method( ),” meaning that you’re able to call obj.my_method(). By contrast, you shouldn’t say that “MyClass has a method named my_method().” That would be confusing, because it would imply that you’re able to call MyClass.my_method() as if it were a class method.

To remove the ambiguity, you should say that my_method() is an instance method (not just “a method”) of MyClass, meaning that it’s defined in MyClass, and you actually need an instance of MyClass to call it. It’s the same method, but when you talk about the class, you call it an instance method, and when you talk about the object, you simply call it a method. Remember this distinction, and you won’t get confused when writing introspective code like this:

String.instance_methods == "abc".methods # => true String.methods == "abc".methods # => false

an object’s instance variables live in the object itself, and an object’s methods live in the object’s class. That’s why objects of the same class share methods but don’t share instance variables.



Related Topics



Leave a reply



Submit