Reputation: 11653
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
Upvotes: 8
Views: 1968
Reputation: 81500
OpenHours::CLOSED is an instance of OpenHours
irb(main):034:0> OpenHours::CLOSED
=> #<OpenHours:0x3ee2e85d @open=0, @close=0>
irb(main):035:0> OpenHours::CLOSED.class
=> OpenHours
To be honest, I don't know what they're doing here. I think it's bad code.
Reply to comment: If you do foo = OpenHours.parse(open, close)
, then the instance will be assigned to foo
Upvotes: 0
Reputation: 168091
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
.
Upvotes: 7
Reputation: 65435
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
.
Upvotes: 6