Calling a Method of a Ruby Singleton Without the Reference of 'Instance'

Ruby: DRY class methods calling Singleton instance methods

The forwardable module will do this. Since you are forwarding class methods, you have to open up the eigenclass and define the forwarding there:

require 'forwardable'
require 'singleton'

class Foo

include Singleton

class << self
extend Forwardable
def_delegators :instance, :foo, :bar
end

def foo
'foo'
end

def bar
'bar'
end

end

p Foo.foo # => "foo"
p Foo.bar # => "bar"

Calling a singleton method within the singleton class in Ruby?

You can define the default value as:

module MyModule
class << self

def process_item(item)
item.capitalize
end

def foo=(item)
@foo_ref=process_item(item)
end

def foo
@foo_ref ||= "initial foo"
end
end
end

What you were trying to do was to set foo to the singleton class, instead of setting foo to the class.

Retrieve a Ruby object from its singleton class?

I'm not aware of any built-in method or keyword but you could write a method that adds a (singleton) method to an object's singleton class, returning the object itself:

class Object
def define_instance_accessor(method_name = :instance)
singleton_class.define_singleton_method(method_name, &method(:itself))
end
end

Usage:

obj = Object.new              #=> #<Object:0x00007ff58e8742f0>
obj.define_instance_accessor
obj.singleton_class.instance #=> #<Object:0x00007ff58e8742f0>

In your code:

class Example
PARENTS = []
PARENTS.define_instance_accessor
class << PARENTS
FATHER = :father
MOTHER = :mother
instance.push(FATHER, MOTHER)
end
end

Internally, YARV stores the object in an instance variable called __attached__. The instance variable doesn't have the usual @ prefix, so it isn't visible or accessible from within Ruby.

Here's a little C extension to expose it:

#include <ruby.h>

static VALUE
instance_accessor(VALUE klass)
{
return rb_ivar_get(klass, rb_intern("__attached__"));
}

void Init_instance_accessor()
{
rb_define_method(rb_cClass, "instance", instance_accessor, 0);
}

Usage:

irb -r ./instance_accessor
> obj = Object.new
#=> #<Object:0x00007f94a11e1260>
> obj.singleton_class.instance
#=> #<Object:0x00007f94a11e1260>
>

How to programmatically remove singleton information on an instance to make it marshal?

You can define custom marshal_dump and marshal_load methods:

class X
def break_marshalling!
meta_class = class << self
self
end
meta_class.send(:define_method, :method_y) do
return
end
end

# This should return an array of instance variables
# needed to correctly restore any X instance. Assuming none is needed
def marshal_dump
[]
end

# This should define instance variables
# needed to correctly restore any X instance. Assuming none is needed
def marshal_load(_)
[]
end
end

# Works fine
restored_instance_of_x =
Marshal.load Marshal.dump(X.new.tap { |x| x.break_marshalling! })

# Does not work
restored_instance_of_x.method_y

If you want you can manage dynamic methods definitions via method_missing:

class X
def method_missing(name, *args)
if name == :method_y
break_marshalling!
public_send name, *args
else
super
end
end
end

# Works fine
Marshal.load(Marshal.dump(X.new)).method_y

Singleton method vs. class method

Most of what happens in Ruby involves classes and modules, containing
definitions of instance methods

class C
def talk
puts "Hi!"
end
end

c = C.new
c.talk
Output: Hi!

But as you saw earlier (even earlier than you saw instance methods inside classes), you can also define singleton methods directly on individual objects:

obj = Object.new
def obj.talk
puts "Hi!"
end
obj.talk
#Output: Hi!

When you define a singleton method on a given object, only that object can call that method. As you’ve seen, the most common type of singleton method is the class method—a method added to a Class object on an individual basis:

class Car
def self.makes
%w{ Honda Ford Toyota Chevrolet Volvo }
end
end

But any object can have singleton methods added to it. The ability to define method- driven behavior on a per-object basis is one of the hallmarks of Ruby’s design.

Singleton classes

Singleton classes are anonymous: although they’re class objects (instances of the class Class ), they spring up automatically without being given a name. Nonetheless, you can open the class-definition body of a singleton class and add instance methods, class methods, and constants to it, as you would with a regular class.

Note:

Every object has two classes:

■ The class of which it’s an instance

■ Its singleton class

----------------------------------------------------------------

At Last I would highly recommends you to watch.

1: The Ruby Object Model and Metaprogramming For detail info about singleton method vs. class method ruby

2: MetaProgramming - Extending Ruby for Fun and Profit - by Dave Thomas

Hope this help you!!!

I want to add a singleton method with a closure to a Ruby object

You can define a method with a block using define_method.

Example:

class Object
def eigenclass
class <<self; self end
end
end

a = "Hello"
other_word = "World"
a.eigenclass.class_eval do
define_method(:cliche) {"#{self} #{other_word}"}
end
a.cliche # => "Hello World"
"Goodbye".cliche # => NoMethodError: undefined method `cliche' for "Goodbye":String

Here is an implementation of a define_singleton_method method:

class Object
def define_singleton_method(name, &block)
eigenclass = class<<self; self end
eigenclass.class_eval {define_method name, block}
end
end

Why can some classes and/or methods be called without instances of their parent class?

First of all, your intuition is correct.

Every methods must be an instance method of some receiver.

Global methods are defined as private instance methods on Object class and hence seem to be globally available. Why? From any context Object is always in the class hierarchy of self and hence private methods on Object are always callable without receiver.

def fuuuuuuuuuuun
end

Object.private_methods.include?(:fuuuuuuuuuuun)
# => true

Class methods are defined as instance methods on the "singleton class" of their class instance. Every object in Ruby has two classes, a "singleton class" with instance methods just for that one single object and a "normal class" with method for all objects of that class. Classes are no different, they are objects of the Class class and may have singleton methods.

class A
class << self # the singleton class
def example
end
end
end

A.singleton_class.instance_methods.include?(:example)
# => true

Alternative ways of defining class methods are

class A
def self.example
end
end

# or

def A.example
end

Fun fact, you can define singleton methods on any object (not just on class objects) using the same syntax def (receiver).(method name) as follows

str = "hello"

def str.square_size
size * size
end

str.square_size
# => 25

"any other string".square_size
# => raises NoMethodError

Some programming language history — Singleton classes are taken from the Smalltalk language where they are called "metaclasses". Basically all object-oriented features in Ruby (as well as the functional-style enumerators on Enumerable) are taken from the Smalltalk language. Smalltalk was an early class-based object-oriented language created in the 70ies. It was also the language that invented graphical user interfaces like overlapping windows and menus et cetera. If you love Ruby maybe also take a look at Smalltalk, you might fall in love yet again.



Related Topics



Leave a reply



Submit