In Ruby, what does define_singleton_method do, and when would you use it instead of define_method?
answer
- one object, not the class
- singleton class holds it
- on a class object: class method
- always public
- Integer receiver: can't define singleton
basics
~20 sdefine_singleton_method adds a method to one object's singleton class, so only that object gets it. Called on a class object it creates a class method, which makes it the tool for generating class-level method families from a list.
solid answer
~40 s`obj.define_singleton_method(:name) { ... }` defines a method on `obj`'s singleton class, so that one object responds and its siblings do not. It takes the same body forms as `define_method`, returns the name as a Symbol, and the body is a closure with `self` as the object. Because classes are objects, calling it in a class body on `self` creates class methods, for example a factory per period from a list. Unlike `define_method`, it is always public, ignoring a bare `private`. I use `define_method` for behaviour every instance shares and `define_singleton_method` for class-level families or a single object that genuinely behaves differently, remembering each such object gets its own singleton class.
code
ruby · 9 linesclass Report
private
define_singleton_method(:weekly) { new }
define_method(:render) { "..." }
end
Report.weekly # works: singleton method is public
Report.new.render # NoMethodError: private method 'render' called for an instance of Reportgo deeper
Recall that define_singleton_method gives a method to one object only, and that on a class it makes a class method.
Explain the singleton class, the always-public visibility, and the shared body forms and Symbol return value with define_method.
Show judgement about per-object methods: singleton class allocation, cache sharing and discoverability, versus a class or a test double.
Decide when class-level method families generated from data are clearer than explicit factory methods for the team.
## What it does `Kernel#define_singleton_method(name) { ... }` defines a method on **one object only**. Ruby gives every object a hidden **singleton class** that sits between the object and its ordinary class; `define_singleton_method` adds the method there. Other instances of the same class do not get it. ```ruby alert = Object.new alert.define_singleton_method(:level) { :critical } alert.level # => :critical Object.new.level # NoMethodError alert.singleton_methods # => [:level] ``` Like `define_method`, it takes the name as a Symbol or String, accepts a block, a Proc, a lambda, a `Method` or an `UnboundMethod` as the body, and returns the name as a Symbol. The body is a closure and runs with `self` set to the object. ## Called on a class, it makes a class method Classes are objects too. Calling `define_singleton_method` on a class object adds a method to that class's singleton class, which is what a **class method** is: ```ruby class Report %i[daily weekly monthly].each do |period| define_singleton_method(:"#{period}") { new(period) } end attr_reader :period def initialize(period) = @period = period end Report.weekly.period # => :weekly ``` Here `self` in the class body is `Report`, so `define_singleton_method` generates three class-level factory methods from a list, something `def self.weekly` could only do one name at a time. ## How it differs from define_method | | `define_method` | `define_singleton_method` | |---|---|---| | defined on | `Module` (classes and modules) | `Kernel` (every ordinary object) | | adds the method to | the receiver class, for all its instances | the receiver's singleton class, for that object only | | visibility | follows a preceding `private` when called in the class body | always public | | return value | name as a Symbol | name as a Symbol | The visibility row is easy to miss: a bare `private` in a class body does **not** make a `define_singleton_method` method private. Use `private_class_method` with the name afterwards if a class-level method should be private. ## Why not just def self.name `def self.weekly` and `class << self` both define singleton methods too, and they are the clearer choice when the names are known in advance. `define_singleton_method` earns its place only when the name is a value: a loop over periods, formats or regions, or a name read from configuration while the class is being built. As with `define_method`, the body can close over a loop variable, and each iteration of `each` gives it a fresh one. ## Typical uses 1. **Class-method families** generated from a list, as in the `Report` example. 2. **One-off behaviour in scripts and consoles**, such as giving a single test object a canned response without defining a class. 3. **Per-object configuration** where one instance really behaves differently, for example a silent logger whose `info` does nothing. In test suites, reaching for it to fake a collaborator usually means a test double from the test framework would be clearer; those also verify and clean up after themselves, whereas a singleton method stays on the object for its lifetime. ## Costs and cautions - **Singleton classes are real objects.** Defining a singleton method allocates one for that object if it has none. Doing it for thousands of objects creates thousands of classes, and method caches keyed by class stop being shared between those objects. - **Some objects cannot have singleton methods.** Integers, Floats and Symbols cannot get a singleton class; calling `define_singleton_method` on `42` raises `TypeError` ("can't define singleton"). - **Frozen objects refuse** new singleton methods with `FrozenError`. - **Discoverability.** A reader looking at the class definition will not see the method; `obj.singleton_methods` lists it at run time. ## What an interviewer is listening for The core answer: it defines a method on one object's singleton class, so on a class object it creates a class method, and unlike `define_method` it is always public. A good answer shows a generated family of class methods and mentions the per-object allocation cost of singleton classes.
- How do you make a generated class method private?Generate it with `define_singleton_method`, then call `private_class_method :name` (it accepts several names). A bare `private` in the class body only changes the default visibility of instance methods defined there, so it has no effect on singleton methods.
- What happens if you call define_singleton_method on the Integer 42?It raises `TypeError` ("can't define singleton"). Integers, Floats and Symbols cannot have a singleton class, so per-object methods cannot be attached to them.
saying these in an interview costs you the question
- define_singleton_method adds the method to every instance of the class
- a bare private in the class body makes it private
- it only works on classes, not on ordinary objects
- defining singleton methods on many objects is free
- it returns the singleton class it modified