Was planning on using factory method to get singleton instance of a ruby class, but I'm not sure if its going to work with Ruby garbage collection.
EG if I have something like:
class Foo
def self.getInstance
##instance = Foo.new if #instance.nil?
return ##instance
end
def counter
#counter
end
def increment
#counter++
end
private
def initialize
#counter = 0
end
end
So the way this works in other languages I'm familiar with that the #instance survives garbage collection indefinitely, so that you Foo.getInstance.increment could be relied to have a continuiously ascending counter for the lifetime of the program.
However, I'm not sure what might be holding on to a reference to the the class's instance variable ##instance so will it get garbage collected?
##instance is a class var, not an instance var. The class holds a references to its class vars which prevents their garbage collection until the class itself is undefined.
Please don't roll your own singleton pattern. The stdlib has a module Singleton which you can mixin to your class to make it a singleton. The stdlib mixin looks after details you've forgotten, such as the thread safety of initialization and undefining new.
Make an instance method 'foo' and an instance variable with the same name as the method '#foo' use the singleton operator ||= to assign or fetch an instance of Foo, If you do this from a class method you have produced a memory leak
def foo
#foo ||= Foo.new
end
The Singleton class is where object methods go when they're specific to that object, and each object may hold or holds such a class.
1.9.3p374 :315 > Jd = class<<self;self;end
=> #<Class:#<Object:0x007ff304078d08>>
1.9.3p374 :316 > jd = Jd.new
TypeError: can't create instance of singleton class
from (irb):316:in `new'
from (irb):316
from /Users/rfatahi/.rvm/rubies/ruby-1.9.3-p374/bin/irb:16:in `<main>'
1.9.3p374 :317 > Jd.class
=> Class
Adding method to Singleton class:
1.9.3p374 :318 > class MyClass
1.9.3p374 :319?> end
=> nil
1.9.3p374 :320 > a = MyClass.new
=> #<MyClass:0x007ff30605b530>
1.9.3p374 :321 > def a.method1
1.9.3p374 :322?> end
=> nil
Related
Why can't we initialize TrueClass in Ruby? I get this:
TrueClass.new # => NoMethodError: undefined method `new' for TrueClass:Class
But, superclass of TrueClass is Object.
Similarly we are unable to initialize NilClass and FalseClass
I just wanted to know how that is possible even if that is the child class of Object. If we wanted to write a class similar to this how can we achieve it?
I just wanted to know how that is possible even if that is the child class of Object. If we wanted to write a class similar to this how can we achieve it?
You can undefine inherited methods using the undef keyword. Since new is a class method, you'll have to use undef inside the class's singleton class. That would look like this:
class <<MyClass
undef new
end
MyClass.new # NoMethodError: undefined method `new' for MyClass:Class
I just wanted to know how that is possible even if that is the child class of Object.
It works by undefining allocate and new. Here's the corresponding C code:
rb_undef_alloc_func(rb_cTrueClass);
rb_undef_method(CLASS_OF(rb_cTrueClass), "new");
You can achieve a similar result in Ruby via undef_method:
class FooClass
::FOO = new # <- this will be the only Foo instance
class << self
undef_method :allocate
undef_method :new
end
end
FooClass.new #=> NoMethodError: undefined method `new' for FooClass:Class
FooClass.allocate #=> NoMethodError: undefined method `allocate' for FooClass:Class
FOO #=> #<FooClass:0x007fddc284c478>
"similar", because TrueClass.allocate doesn't actually raise a NoMethodError, but a TypeError:
TrueClass.allocate #=> TypeError: allocator undefined for TrueClass
Unfortunately, rb_undef_alloc_func is not available from within Ruby. We could mimic the behavior by overriding allocate:
class FooClass
class << self
def allocate
raise TypeError, "allocator undefined for #{self}"
end
undef_method :new
end
end
FooClass.allocate #=> TypeError: allocator undefined for FooClass
Not sure, which approach is cleaner.
The above changes prevent you from creating an instance via new, but there are other ways:
FOO #=> #<FooClass:0x007fddc284c478>
FOO.dup #=> #<FooClass:0x007fad721122c8>
FOO.clone #=> #<FooClass:0x007f83bc157ba0>
Marshal.load(Marshal.dump(FOO)) #=> #<FooClass:0x007f83bc13e330>
To account for all these special cases, Ruby' stdlib provides the Singleton module:
require 'singleton'
class Foo
include Singleton
end
It works by making allocate and new private methods: (among other changes)
Foo.new #=> NoMethodError: private method `new' called for Foo:Class
Foo.allocate #=> NoMethodError: private method `new' called for
And it adds instance which returns an instance: (or the instance, there's only one)
Foo.instance #=> #<Foo:0x007fdca11117e8>
class Invoice
def Invoice.generate(order_id, charge_amount, credited_amount = 0.0)
Invoice.new(:order_id => order_id, :amount => charge_amount, :invoice_type => PURCHASE, :credited_amount => credited_amount)
end
end
Why would you create Invoice.generate inside Invoice class rather than self.generate?
self.generate is easier to work with, whereas Invoice.generate is arguably more explicit. Other than that, there's no difference between the two.
Explanation
You can define a method on any instance using this form
def receiver.method(args)
end
Check this out
class Foo
end
def Foo.bar
"bar"
end
Foo.bar # => "bar"
And yes, I mean any instance. It's absolutely possible that one instance has some method while another doesn't
f = Foo.new
def f.quux
'quux'
end
f2 = Foo.new
f.quux # => "quux"
f2.quux # => # ~> -:20:in `<main>': undefined method `quux' for #<Foo:0x007fe4e904a6c0> (NoMethodError)
A reminder: inside of class definition (but outside of method definitions) self points to that class.
class Foo
# self is Foo
end
So, armed with this knowledge, the difference between self.generate and Invoice.generate should be obvious.
Under normal circumstances, it would practically have no difference from def self.generate.
The only edge case I can think of is if you have a nested class with the same name, then the explicit version would apply only to the nested class.
class A
def self.x
name
end
def A.y
name
end
class A
# nested class A::A
end
def self.p
name
end
def A.q
name
end
end
> A.x # => "A"
> A.y # => "A"
> A.p # => "A"
> A.q # => NoMethodError: undefined method `q' for A:Class
> A::A.q # => "A::A"
As you see, after a nested class with the same name is defined, subsequent explicit class method definitions made with the class name refer to the nested class, but explicit definitions made beforehand refer to the original.
Implicit definitions made with self always refer to the base class.
You have 2 ways for defining a class method.
1) You can use the name of the class directly
class Test #Test is now an instance of a built-in class named Class
def Test.class_method
"I'm a class method."
end
end
2) You can use the self variable, which is always pointing to the current object
class Test
def self.class_method
"I'm a class method."
end
end
Once you understand that classes are objects, this use of the self variable to define a class method finally makes sense.
The value of self
Not too surprinsingly, when you are inside a class method, the value of self refers to the object that holds the class structure (the instance of class Class). This means that :
class Test
def self.class_method
self.x
end
end
is equivalent to :
class Test
def self.class_method
Test.x
end
end
When you are inside an instance method, the value of self still refers to the current object. This time however, the current object is an instance of class Test, not an instance of class Class.
More info. : http://www.jimmycuadra.com/posts/self-in-ruby
Is there a method in Ruby that refers to the current instance of a class, in the way that self refers to the class itself?
self always refers to an instance, but a class is itself an instance of Class. In certain contexts self will refer to such an instance.
class Hello
# We are inside the body of the class, so `self`
# refers to the current instance of `Class`
p self
def foo
# We are inside an instance method, so `self`
# refers to the current instance of `Hello`
return self
end
# This defines a class method, since `self` refers to `Hello`
def self.bar
return self
end
end
h = Hello.new
p h.foo
p Hello.bar
Output:
Hello
#<Hello:0x7ffa68338190>
Hello
Within an instance method of a class self refers to that instance. To get the class within an instance you can call self.class. If you call self within a class method, you get the class. Inside a class method you can't access any instance of the class.
The self reference is always available, and the object it points to depends on the context.
class Example
self # refers to the Example class object
def instance_method
self # refers to the receiver of the :instance_method message
end
end
the method self refers to the object it belongs to. Class definitions are objects too.
If you use self inside class definition it refers to the object of class definition (to the class) if you call it inside class method it refers to the class again.
But in the instance method it refers to the object which is an instance of the class.
1.9.3p194 :145 > class A
1.9.3p194 :146?> puts "%s %s %s"%[self.__id__, self, self.class] #1
1.9.3p194 :147?> def my_instance_method
1.9.3p194 :148?> puts "%s %s %s"%[self.__id__, self, self.class] #2
1.9.3p194 :149?> end
1.9.3p194 :150?> def self.my_class_method
1.9.3p194 :151?> puts "%s %s %s"%[self.__id__, self, self.class] #3
1.9.3p194 :152?> end
1.9.3p194 :153?> end
85789490 A Class
=> nil
1.9.3p194 :154 > A.my_class_method #4
85789490 A Class
=> nil
1.9.3p194 :155 > a=A.new
=> #<A:0xacb348c>
1.9.3p194 :156 > a.my_instance_method #5
90544710 #<A:0xacb348c> A
=> nil
1.9.3p194 :157 >
You see puts #1 which executes during class declaration. It shows that class A is an object of type Class with id ==85789490. So inside class declaration self refers to the class.
Then when class methods is invoked (#4) self inside class method (#2) again refers to that class.
And when an instance method is invoked (#5) it shows that inside it (#3) self refers to the object of the class instance which the method is attached to.
If you need to refer the class inside an instance method use self.class
may be you need :itself method?
1.itself => 1
'1'.itself => '1'
nil.itself => nil
hope this help!
I'm stuck. I'm trying to dynamically define a class method and I can't wrap my head around the ruby metaclass model. Consider the following class:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
end
Example.class_instance.class # => Class
Example.meta.class # => Class
Example.class_instance == Example # => true
Example.class_instance == Example.meta # => false
Obviously both methods return an instance of Class. But these two instances
are not the same. They also have different ancestors:
Example.meta.ancestors # => [Class, Module, Object, Kernel]
Example.class_instance.ancestors # => [Example, Object, Kernel]
What's the point in making a difference between the metaclass and the class instance?
I figured out, that I can send :define_method to the metaclass to dynamically define a method, but if I try to send it to the class instance it won't work. At least I could solve my problem, but I still want to understand why it is working this way.
Update Mar 15, 2010 13:40
Are the following assumptions correct.
If I have an instance method which calls self.instance_eval and defines a method, it will only affect the particular instance of that class.
If I have an instance method which calls self.class.instance_eval (which would be the same as calling class_eval) and defines a method it will affect all instances of that particular class resulting in a new instance method.
If I have a class method which calls instance_eval and defines a method it will result in a new instance method for all instances.
If I have a class method which calls instance_eval on the meta/eigen class and defines a method it will result in a class method.
I think it starts to make sense to me. It would certainly limit your possibilities if self inside an class method would point to the eigen class. If so it would not be possible to define an instance method from inside a class method. Is that correct?
Defining a singleton method dynamically is simple when you use instance_eval:
Example.instance_eval{ def square(n); n*n; end }
Example.square(2) #=> 4
# you can pass instance_eval a string as well.
Example.instance_eval "def multiply(x,y); x*y; end"
Example.multiply(3,9) #=> 27
As for the difference above, you are confusing 2 things:
The meta class defined by you, is what called in Ruby community as singelton class or eigen class. That singleton class is the class that you can add class(singleton) methods to.
As for the class instance you are trying to define using the class_instance method, is nothing but the class itself, to prove it, just try adding an instance method to the class Example and check if the class_instance method defined by you returns the class Example itself by checking the existence of that method:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
def hey; puts hey; end
end
Example.class_instance.instance_methods(false) #=> ['hey']
Anyway to sum it for you, when you want to add class methods, just add them to that meta class. As for the class_instance method is useless, just remove it.
Anyway I suggest you read this post to grasp some concepts of Ruby reflection system.
UPDATE
I suggest you read this nice post: Fun with Ruby's instance_eval and class_eval,
Unfortunately class_eval and instance_eval are confusing because they somehow work against their naming!
Use ClassName.instance_eval to define class methods.
Use ClassName.class_eval to define instance methods.
Now answering your assumptions:
If I have an instance method which
calls self.instance_eval and defines a
method, it will only affect the
particular instance of that class.
yes:
class Foo
def assumption1()
self.instance_eval("def test_assumption_1; puts 'works'; end")
end
end
f1 = Foo.new
f1.assumption1
f1.methods(false) #=> ["test_assumption_1"]
f2 = Foo.new.methods(false) #=> []
If I have an instance method which
calls self.class.instance_eval (which
would be the same as calling
class_eval) and defines a method it
will affect all instances of that
particular class resulting in a new
instance method.
no instance_eval in that context will define singleton methods(not instance ones) on the class itself:
class Foo
def assumption2()
self.class.instance_eval("def test_assumption_2; puts 'works'; end")
end
end
f3 = Foo.new
f3.assumption2
f3.methods(false) #=> []
Foo.singleton_methods(false) #=> ["test_assumption_2"]
For that to work replace instance_eval with class_eval above.
If I have a class method which calls
instance_eval and defines a method it
will result in a new instance method
for all instances.
Nope:
class Foo
instance_eval do
def assumption3()
puts 'works'
end
end
end
Foo.instance_methods(false) #=> []
Foo.singleton_methods(false) #=> ["assumption_3"]
That will make singleton methods, not instance methods. For that to work replace instance_eval with class_eval above.
If I have a class method which calls
instance_eval on the meta/eigen class
and defines a method it will result in
a class method.
well no, that will make so sophisticated stuff, as it will add singleton method to the singleton class, I don't think that will have any practical use.
If you define a method on a class, it can be invoked on its objects. It is an instance method.
class Example
end
Example.send :define_method, :foo do
puts "foo"
end
Example.new.foo
#=> "foo"
If you define a method on a metaclass, it can be invoked on the class. This is similar to the concept of a class method or static method in other languages.
class Example
def self.metaclass
class << self
self
end
end
end
Example.metaclass.send :define_method, :bar do
puts "bar"
end
Example.bar
#=> "bar"
The reason that metaclasses exist is because you can do this in Ruby:
str = "hello"
class << str
def output
puts self
end
end
str.output
#=> "hello"
"hi".output
# NoMethodError
As you can see, we defined a method that is only available to one instance of a String. The thing that we defined this method on is called the metaclass. In the method lookup chain, the metaclass is accessed first before searching the object's class.
If we replace the object of type String with an object of type Class, you can imagine why this means we're only defining a method on a specific class, not on all classes.
The differences between the current context and self are subtle, you can read more if you're interested.
What does class << self do in Ruby?
First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
Now, to answer the question: class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods:
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
This can also be written as a shorthand:
class String
def self.value_of obj
obj.to_s
end
end
Or even shorter:
def String.value_of obj
obj.to_s
end
When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.
I found a super simple explanation about class << self , Eigenclass and different type of methods.
In Ruby, there are three types of methods that can be applied to a class:
Instance methods
Singleton methods
Class methods
Instance methods and class methods are almost similar to their homonymous in other programming languages.
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
Another way of accessing an Eigenclass(which includes singleton methods) is with the following syntax (class <<):
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
now you can define a singleton method for self which is the class Foo itself in this context:
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
Usually, instance methods are global methods. That means they are available in all instances of the class on which they were defined. In contrast, a singleton method is implemented on a single object.
Ruby stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.
If multiple singleton methods are defined within a single object, they are all stored in the same metaclass.
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
In the above example, class << z1 changes the current self to point to the metaclass of the z1 object; then, it defines the say_hello method within the metaclass.
Classes are also objects (instances of the built-in class called Class). Class methods are nothing more than singleton methods associated with a class object.
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.
Additional info can be found at this post about Ruby Classes.
What class << thing does:
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[it makes self == thing.singleton_class in the context of its block].
What is thing.singleton_class?
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi object inherits its #methods from its #singleton_class.instance_methods and then from its #class.instance_methods.
Here we gave hi's singleton class instance method :a. It could have been done with class << hi instead.
hi's #singleton_class has all instance methods hi's #class has, and possibly some more (:a here).
[instance methods of thing's #class and #singleton_class can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]
By the way - they call object's singleton class == metaclass == eigenclass.
А singleton method is a method that is defined only for a single object.
Example:
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
Singleton's methods of SomeClass
test
Singleton's methods of test_obj
test_2
test_3
In fact if you write any C extensions for your Ruby projects there is really only one way to define a Module method.
rb_define_singleton_method
I know this self business just opens up all kinds of other questions so you could do better by searching each part.
Objects first.
foo = Object.new
Can I make a method for foo?
Sure
def foo.hello
'hello'
end
What do I do with it?
foo.hello
==>"hello"
Just another object.
foo.methods
You get all the Object methods plus your new one.
def foo.self
self
end
foo.self
Just the foo Object.
Try to see what happens if you make foo from other Objects like Class and Module. The examples from all the answers are nice to play with but you have to work with different ideas or concepts to really understand what is going on with the way the code is written. So now you have lots of terms to go look at.
Singleton,
Class,
Module,
self,
Object,
and Eigenclass was brought up but Ruby doesn't name Object Models that way. It's more like Metaclass.
Richard or __why shows you the idea here.
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
And if the blows you away then try looking up Ruby Object Model in search.
Two videos that I know of on YouTube are Dave Thomas and Peter Cooper. They try to explain that concept too. It took Dave a long time to get it so don't worry.
I'm still working on it too. Why else would I be here?
Thanks for your question.
Also take a look at the standard library. It has a Singleton Module just as an FYI.
This is pretty good.
https://www.youtube.com/watch?v=i4uiyWA8eFk