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:
- you don't need to redefine
method_missing
(less magic -> less pain when you debug the code) - 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)
- (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
New Way of Creating Hashes in Ruby 2.2.0
Bundler: Not Executable: Script/Delayed_Job
Recursive Rails Nested Resources
Rescuing "Command Not Found" for Io::Popen
Which Global Variable Is for Last Expression
Uml Sequence Diagram - How to Represent Method Arguments That Instantiate Objects
Ruby Regexp to Replace Equations
How to Collapse Double Splat Arguments into Nothing
Using the Right Exception Subclass in Ruby
Openssl Causing Very Slow Rails Boot Time on Windows
Ruby Open-Uri Can't Open Url (M1 MAC)
Why Does My Recursive Method from Helper Not Return Every Value
Why Can't I Change the Value of Self
Gem Install Therubyracer -V 0.11.4 Fails on Os X 10.10
How to Convert This Ruby String into an Array
Differencebetween a Constant and a Variable in Ruby
Reverse a String Each Two Characters with Ruby
Ruby: Looking for Ruby-Embeddable Interpreter or Scripting Language