Calling Ruby Method Without Instantiating Class

Calling ruby method without instantiating class

There are several kinds of methods. The two most important ones are: instance methods and class instance methods.

Foo.first is a class instance method. It works on a class instance (Foo, in this case). If it stores some data inside the class, that data is shared globally across your program (because there's only one class with name Foo (or ::Foo, to be exact)).

But your greeting method is an instance method, it requires object instance. If your greeting method will use Person's name, for example, it has to be instance method, so that it will be able to use instance data (the name). If it doesn't use any instance-specific state and you really meant it to be a class instance method, then use the self "prefix".

class Person < ActiveRecord::Base
def self.greeting
'hello'
end
end

How to call any instance method in ruby object without instantiating it?

Despite the fact method_missing would do the job, I'd probably avoid it in this case in favor of a more explicit delegation. Simple and dirty example:

module InstanceDelegator
def delegate_to_instance(*methods)
methods.each do |method_name|
define_singleton_method method_name do |*args|
new(*args).public_send(method_name)
end
end
end
end

class Foo
extend InstanceDelegator

delegate_to_instance :bar # <- define explicitly which instance methods
# should be mirrored by the class ones

def bar
puts "bar is called"
end

def baz
puts "baz is called"
end
end

# and then

Foo.bar # => bar is called
Foo.baz # NoMethodError ...

# reopening works too
class Foo
delegate_to_instance :baz
end

Foo.baz # baz is called

Pros:

  1. you don't need to redefine method_missing (less magic -> less pain when you debug the code)
  2. you control precisely which instance methods to be wrapped with the class level "shorthand" (fewer chances to delegate something you don't want to - more robust code)
  3. (minor) no need to raise NoMethodError explicitly - you can fully rely on the core dispatching as it is...

ruby: calling a instance method without using instance

Message ist an module. Your Class SimpleFile includes this module. so the module methods included in your class SimpleFile. that means, all module methods can now be used like as methods from SimpleFile

see http://ruby-doc.org/core-2.2.0/Module.html for more infos about module in ruby. it's a great feature.

How do I create a class without 'new' method?

You have several options, which I will present here (roughly) in the order of how "aggressive" they are in my personal opinion:

Override the default Object#initialize with your own

You can override the default implementation of Object#initialize with your own implementation which does something different. In your case, say, raise an Exception:

class Foo
def initialize(*) raise TypeError, "`#{self.class}` cannot be instantiated." end
end

Foo.new
# TypeError: `Foo` cannot be instantiated.
# from (…):5:in `initialize'

The default implementation of Class#new will automatically call your implementation of Foo#initialize, which will then raise an Exception and abort the object construction, or more precisely: it will abort the object initialization, since the object will have been constructed by the time initialize is called (otherwise, how would you call initialize if there is no object to call it on?) However, object construction is cheap, and the object will immediately be eligible for garbage collection, so it shouldn't matter.

For completeness' sake, here is (approximately) what the default implementation of Class#new looks like:

class Class
def new(*args, &b)
obj = allocate
obj.send(:initialize, *args, &b) # `initialize` is `private`, must use `send`
obj
end
end

As you can see, by the time initialize is called, Class#allocate will have already constructed the object.

Override the default Class#new with your own

You can override the default implementation of Class#new with your own implementation which does something different. In your case, say, raise an Exception:

def Foo.new(*) raise TypeError, "`#{self}` cannot be instantiated." end

Foo.new
# TypeError: `Foo` cannot be instantiated.
# from (…):3:in `new'

Make Foo::new a private method

You can make the new method of the singleton class of Foo a private method, that way, it can't be called with an explicit receiver:

Foo.private_class_method :new

Foo.new
# NoMethodError: private method `new' called for Foo:Class
# from (…):3:in `…'

This would, for example, still allow you to have special factory methods that construct instances of your class, e.g. something like:

def Foo.create_from_xml(file)
# do stuff to parse `file`
new(argument_parsed_from_file)
end

Note this sentence in the documentation of Module#private_class_method:

Often used to hide the default constructor new.

and the code example directly following it.

Undefine the new method from the singleton class of Foo

You could undefine the new method using Module#undef_method. undef_method will prevent instances of the module from responding to that message completely, unlike Module#remove_method, which will simply remove the method from the module, so that method lookup continues normally up the inheritance chain.

Foo.singleton_class.undef_method :new

Foo.new
# NoMethodError: undefined method `new' for Foo:Class
# from (…):3:in `…'

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

When creating a method without a class in the Rails console, what class is the method under?

Ruby creates a object of Object class when you run your console, so all methods are private instance methods of Object class, you can run this to verify.

        Object.private_instance_methods.include? :test

So when you define your methods in console It is interpreted to this

class Object
def test
puts "hi"
end
end

More explanation

I was wanted to explain this but a detailed article is written on this topic,

https://www.sitepoint.com/rubys-top-self-object/

Is it possible to access a method without creating an instance?

I believe you're looking for what is known as a class method in Ruby:

module SomeModule
class SomeClass
@class_variable = "some_string" # An instance variable on a class

def self.some_class_method
@class_variable # Return can be omitted in Ruby
end

# This is how setter methods are usually written in Ruby
def self.some_class_method= new_value
@class_variable = new_value
end
end
end

SomeModule::SomeClass.some_class_method
#=> "some_string"

Ruby: 'new' without a class

When the receiver is self, the receiver can be omitted. The first two new calls that you are questioning are called within the context of OpenHours, which means that self is set to OpenHours. Therefore new without the explicit receiver is equivalent to self.new and OpenHours.new. In your third example, the context is an instance of OpenHours. self refers to that instance, and self.class refers to OpenHours, so self.class.new is equivalent to OpenHours.new. In all cases, the created object is an instance of OpenHours.



Related Topics



Leave a reply



Submit