My understanding of Ruby was that the 'new' keyword was always combined with a class name to create a new instance of a class. In the code below, found at https://gist.github.com/e9c0da1a6e92dd12cbc7, which was submitted as a solution to a Ruby Programming Challenge for Newbies contest, the author uses the 'new' keyword three times without instantiating a class.
In one case, new(0,0) is assigned to a constant CLOSED. In another case, new(open,close) is a return value from a function. Why do it this way? What is 'new' doing when it's used this way? what is it creating?
class OpenHours
attr_reader :open, :close
def initialize(open, close)
@open, @close = open, close
end
def duration
@duration ||= @open < @close ? @close - @open : 0
end
CLOSED = new(0, 0) #first new
def self.parse(open, close)
open = Time.parse(open)
close = Time.parse(close)
open = TimeUtils::seconds_from_midnight(open)
close = TimeUtils::seconds_from_midnight(close)
new(open, close) #second new
end
def offset(seconds)
self.class.new([@open, seconds].max, @close) #third new
end
end
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
.
In Ruby, new
is not an operator or keyword. It is an instance method of Class
instances. For example, the object OpenHours
is a class, and therefore is an instance of Class
, and therefore has an instance method new
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With