Reputation: 139
This is a job interview problem. I'm supposed to create a data structure for a time in seconds and milliseconds, then create two Time
objects, and then write a function that can return the difference between the two Time
s. This is my code:
class Time
def initialize (sec, milli_sec)
@sec = sec
@milli_sec = milli_sec
end
def difference(time_2)
puts @sec.to_i*1000 + @milli_sec.to_i + time_2.@sec
end
end
time_1 = Time.new('5','30')
time_2 = Time.new('6','40')
time_1.difference(time_2)
This is the error:
syntax error, unexpected tIVAR, expecting '('
I am having a problem accessing the @sec
, @milli_sec
variables of time_2
passed as time_1.difference(time_2)
. I think that the syntax is [email protected]_i
or time_2.#@sec.to_i
, but those return errors. time_2.sec
returns uninitialized time, even though it looks like it's been initialized. I would like to know the solution to this problem.
Upvotes: 2
Views: 953
Reputation: 85
The same objective can be achieved in much lesser lines of code using approach as below:-
class MyTime
attr_accessor :seconds, :milli_seconds
def initialize(entity={})
@seconds = entity['seconds']
@milli_seconds = entity['milli_seconds']
end
def difference(obj)
ms= ((@seconds.to_i*1000+@milli_seconds.to_i)-(obj.seconds.to_i*1000+obj.milli_seconds.to_i))
secs = ms/1000
msecs = ms%1000
return MyTime.new({'seconds'=> secs,
'milli_seconds'=> msecs})
end
end
time_1 = MyTime.new({'seconds'=> '20',
'milli_seconds'=> '100'})
time_2 = MyTime.new({'seconds'=> '10',`enter code here`
'milli_seconds'=> '20'})
diff_Obj = time_1.difference(time_2)
puts "Difference is : #{diff_Obj.seconds} Seconds #{diff_Obj.milli_seconds} milliseconds"
Upvotes: 0
Reputation: 139
Here is my final solution:
class Moment
def initialize (sec, milli_sec)
@sec = sec
@milli_sec = milli_sec
end
def sec
@sec
end
def milli_sec
@milli_sec
end
def difference(time_2)
return ((@sec.to_i*1000 + @milli_sec.to_i) - (time_2.sec.to_i*1000 + time_2.milli_sec.to_i)).abs
end
end
time_1 = Moment.new('1','300')
time_2 = Moment.new('11','20')
time_1.difference(time_2)
Upvotes: 0
Reputation: 8898
In ruby, every interface is a group of methods. You can't just obj.@var
to access instance variables since they are not methods thus not interfaces. If you want to expose instance variables, then create public methods to access them. attr_reader
and attr_accessor
are simply handy ways to create those methods.
Upvotes: 1
Reputation: 19899
@sec
and @milli_sec
are instance variables of your Time
class. This means that unless you do something else only the instance itself has access to them. Other parts of your code can create an instance, but are only able to access the methods you specify. The point of this is so that you can change the underlying implementation without affecting other parts of your code that are using this class.
There are a variety of ways to do this. You could define the following two methods in your Time
class:
def sec
@sec
end
def milli_sec
@milli_sec
end
These methods are public (by default) so you can now do this:
t = Time.new(1, 2)
puts t.sec # prints 1
puts t.milli_sec # prints 2
A more Ruby-ish way would be to add this line to the top of your class:
attr_reader :sec, :milli_sec
Doing this accomplishes the same thing as defining the two methods above. You might also want to look at attr_accessor
.
P.S. Time
is a poor choice of class name for your own code as it's already defined by Ruby itself.
Upvotes: 4