Reputation: 701
I'm trying out some of the exercises over on exercism. Each exercise comes with a set of pre-written tests that we need to make pass. The problem I'm currently working on asks us to write a Robot class. Each robot should come with a method called name that sets a default name. I'm doing that like this:
class Robot
attr_accessor :name
def self.name
@name = DateTime.now.strftime("%y%^b%k%M%S")
@name
end
end
The problem is that the first test (I'm skipping over the rest for now) keeps failing. Here's the test:
def test_has_name
# rubocop:disable Lint/AmbiguousRegexpLiteral
assert_match /^[A-Z]{2}\d{3}$/, Robot.new.name
# rubocop:enable Lint/AmbiguousRegexpLiteral
end
I'm not using the rubocop gem so I've left the commented lines as is. The test fails with this error:
1) Failure:
RobotTest#test_has_name [robot-name/robot_name_test.rb:7]:
Expected /^[A-Z]{2}\d{3}$/ to match nil.
I suppose the biggest problem is that I don't really understand the error and I don't know if I need to install rubocop and uncomment those lines above or of my code is just plain wrong. Any help at all with this would be much appreciated.
Upvotes: 0
Views: 69
Reputation:
Your method is a class method. Which means that Robot.name
will give you the name, while Robot.new.name
is nil
.
You want to use:
def name
#code
end
Instead of self.name
.
You can also set name in the initialize
method:
def initialize
@name = 'RB123'
end
Upvotes: 1
Reputation: 52357
There is number of issues with your code.
First, you define accessor :name
, but you don't have initialize
method.
What you have defined, is a class method name
, which would work if you call Robot.name
.
To make your class work, it should look like this:
class Robot
def initialize
@name = DateTime.now.strftime("%y%^b%k%M%S")
end
end
Robot.new.name
#=> "15MAY150035"
Or You would do
class Robot
def name
DateTime.now.strftime("%y%^b%k%M%S")
end
end
Robot.new.name
#=> "15MAY150649"
Also, in Ruby last line in method is already what would be return
ed, so you don't have to write @name
here:
def self.name
@name = DateTime.now.strftime("%y%^b%k%M%S")
@name # useless
end
Furthermore, variable @name
is useless here, since method name
either way will return DateTime
object.
You have to make sure you understand what is what in Ruby.
Upvotes: 1
Reputation: 46667
Your code defines name
to be a method on the Robot
class (that's what the self
indicates; and @name
here will be setting a member variable on the class object). You need to provide a way for each instance to have a name.
As a secondary concern, your method changes the name everytime name
is called. You probably want to set it once (when the robot is initialize
d, probably!), then return that each time.
Upvotes: 1