Singleton classes are classes which can be instantiated only once.
There are various ways to create a singleton class or methods in Ruby as below:
class Logger
def self.log(msg)
@@log ||= File.open("log.txt", "a")
@@log.puts(msg)
end
end
Logger.log('message 5')
module Logger
def self.log(msg)
@@log ||= File.open("log.txt", "a")
@@log.puts(msg)
end
end
Singleton class can also contain yield
, which when called with a block will
execute the block. As shown below
def foo
class << Object.new
yield
end
end
foo { puts "Hello Ruby!" }
=> "Hello Ruby!"
Before Ruby 2.7 this function gets executed without any warnings or errors.
In Ruby 2.7
In Ruby 2.7 a warning will be issued when the above function is executed.
def foo
class << Object.new
yield
end
end
warning: `yield' in class syntax will not be supported from Ruby 3.0. [Feature #15575]
foo { puts "Hello Ruby!" }
=> "Hello Ruby!"
This will be deprecated since yield
in singleton class syntax was inconsistent
with local variables accessibility.
Consider below example
def foo
x = 1
class << Object.new
p x # NameError (undefined local variable or method) -- enclosing scope NOT accessible
yield # calls block passed to foo, implying enclosing scope IS accessible
# In Ruby 2.7: warning: `yield' in class syntax will not be supported from Ruby 3.0.
end
end
foo { p "Hello Ruby!" }
The above code raises error as shown below
NameError (undefined local variable or method `x' for #<Class...>
NOTE: The variables declared in the block are accessible in the enclosing scope of the singleton class.
def foo
class << Object.new
yield
end
end
foo { x = 1; p x }
=> 1