Trying to figure out what's wrong with this code - ruby

I can't come up with a solution.
class Person
def initialize(name)
#name = name
end
def greet(other_name)
#other_name
print "Hi #{#other_name}, my name is #{#name}"
end
end
kit = Person.new("Tom", "Jerry")
kit.greet
I would appreciate a helping hand.

You have to make a decision:
Do you want to provide both names when initializing the Person:
class Person
def initialize(name, other)
#name = name
#other = other
end
def greet
puts "Hi #{#other}, my name is #{#name}"
end
end
kit = Person.new("Tom", "Jerry")
kit.greet
#=> Hi Jerry, my name is Tom
Or do you want to provide the second name when calling the greet method:
class Person
def initialize(name)
#name = name
end
def greet(other)
puts "Hi #{other}, my name is #{#name}"
end
end
kit = Person.new("Tom")
kit.greet("Jerry")
#=> Hi Jerry, my name is Tom

In the initialize method, you should take in two parameters, because you are calling it with two. You were declaring the #other_name variable inside the greet function instead of the initialize one.
This will work.
class Person
def initialize(name, other_name)
#name = name
#other_name = other_name
end
def greet
print "Hi #{#other_name}, my name is #{#name}"
end
end
kit = Person.new("Tom", "Jerry")
kit.greet
https://repl.it/C5wn

Consider writing your code like this:
class Person
attr_reader :name
def initialize(name)
#name = name
end
def greet(person)
puts "Hi #{person.name}, my name is #{name}"
end
end
tom = Person.new("Tom")
jer = Person.new("Jerry")
tom.greet(jer) #=> Hi Jerry, my name is Tom.
This way you actually have another person as an object instead of just a name.

Related

How do I get the string value in this string interpolation

I've been trying to get this code to output:
'Mary has a pet called Satan.'
But what I get is:
'Mary has a pet called #<Cat:0x00000002784c20>'
Code Below:
class Person
def initialize(name)
#name = name
#pet = nil
#hobbies = []
end
def describe()
puts "This persons name is #{#name}."
puts "#{#name}'s hobbies are:"
#hobbies.map { |hobby| puts hobby }
if #pet == nil
puts "#{#name} has not got any pets."
else
puts "#{#name} has a pet called #{#pet}"
end
end
attr_accessor :pet, :hobbies
end
class Cat < Animal
def initialize(name)
#name = name
end
end
satan = Cat.new("Satan")
mary = Person.new("Mary")
mary.pet = satan
mary.describe
Thanks for all your help.
In your describe() function, you are calling the object Cat without specifing the name.
But if you call #{pet.name} it will throw:
<undefined method `name' for #<Cat:0x0055d750a1a450 #name="Satan">
You have to allow the access to the variable name in the Cat class first with attr_accessor
class Cat < Animal
attr_accessor :name # First allow access
end
class Person
def describe()
puts "#{#name} has a pet called #{#pet.name}" # Then call the pet's name!
end
end

Ruby access instance variables from another method

I have a class and I try to access an instance variable and I noticed I can do it in both ways by addressing it with # and without it. Why si there no error when I call it without a # puts "name : #{name}"?
class Blabla
attr_accessor :name
def initialize(blabla)
#name = blabla
end
def populate()
puts "name : #{name}"
puts "name : #{#name}"
end
end
As hinted in the comments:
attr_accessor :name
is shorthand for:
def name
#name
end
def name=(name)
#name = name
end
So expanding your code we have:
class Blabla
def name
#name
end
def name=(name)
#name = name
end
def initialize(blabla)
#name = blabla
end
def populate()
puts "name : #{name}"
puts "name : #{#name}"
end
end
#{name} references the method name which returns #name.
#{#name} references #name directly.
Also be sure to understand attr_reader, attr_writer methods.

Console printing backwards

I'm trying to get the code to print the name of a class and then greetings on the same line. For example:
(DriveThru): Hi, welcome to Starbucks! What can I get started for you?
Here's my code:
module Order
def order_drink
"(#{self.class.name}): #{self.greeting}"
end
end
class Lobby
include Order
attr_reader :name
def initialize(name)
#name = name
end
def greeting
puts "Hi, welcome to Starbucks! How are you doing today #{self.name}?"
end
end
class DriveThru
include Order
attr_reader :name
def initialize(name)
#name = name
end
def greeting
puts "Hi, welcome to Starbucks! What can I get started for you #{self.name}?"
end
end
dt = DriveThru.new("Tom")
lb = Lobby.new("Jessica")
puts dt.order_drink
puts lb.order_drink
When I run the code, it prints the greeting first, line breaks, then prints the class name like this:
"Hi, welcome to Starbucks! What can I get started for you?"
(DriveThru):
What am I'm doing wrong?
Your greeting function is executing the puts statement. Due to the way Ruby (and most other programming languages) works, the order_drink method will evaluate the contents of the greeting method (calling a puts statement) first before returning its own value.
Dropping the puts at the beginning of each greeting function, for example:
class Lobby
include Order
attr_reader :name
def initialize(name)
#name = name
end
def greeting
"Hi, welcome to Starbucks! How are you doing today #{self.name}?"
end
end
This will cause your script to output the following:
(DriveThru): Hi, welcome to Starbucks! What can I get started for you Tom?
(Lobby): Hi, welcome to Starbucks! How are you doing today Jessica?
That said, it'd be preferable to add an attr_reader for the greeting attribute, and set its value in the initialize method (also known as the constructor), like so:
class Lobby
include Order
attr_reader :name, :greeting
def initialize(name)
#name = name
#greeting = "Hi, welcome to Starbucks! How are you doing today #{name}?"
end
end

Basic Ruby class - correct code so it returns expected value

Extremely basic, yet I can't figure it out! Noob issues - I have tried several different answers for this, and I am still getting argument errors. Can someone please help enlighten me on the correct answer?
Correct this code, so that the greet function returns the expected value.
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{name}"
end
end
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{#name}"
end
end
You need to access your instance variables by prefixing the variable name with #. Just the same way as when you assigned it.
name is not available in greet. You can either use #name, or add an accessor:
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{#name}"
end
end
or
class Person
attr_accessor :name
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{name}"
end
end

I can not use in-class assigned property of a class in Ruby

Well, I can do this:
class Person
attr_accessor :name
def greeting
"Hello #{#name}"
end
end
p = Person.new
p.name = 'Dave'
p.greeting # "Hello Dave"
but when I decide to assign the property in the class itself it doesnt work:
class Person
attr_accessor :name
#name = "Dave"
def greeting
"Hello #{#name}"
end
end
p = Person.new
p.greeting # "Hello"
This is the default behavior, albeit a confusing one (especially if you're used to other languages in the OOP region).
Instance variables in Ruby starts being available when it is assigned to and normally this happens in the initialize method of your class.
class Person
def initialize(name)
#name = name
end
end
In your examples you're using attr_accessor, this magical method produces a getter and a setter for the property name. A Person#name and Person#name=, method is created which overrides your "inline" instance variable (that's why your first example works and the second one doesn't).
So the proper way to write your expected behaviour would be with the use of a initialize method.
class Person
def initialize(name)
#name = name
end
def greeting
"Hello, #{#name}"
end
end
Edit
After a bit of searching I found this awesome answer, all rep should go to that question.
Think of a Person class as a blueprint that you can create single person instances with. As not all of these person instances will have the name "Dave", you should set this name on the instance itself.
class Person
def initialize(name)
#name = name
end
attr_accessor :name
def greeting
"Hello #{#name}"
end
end
david = Person.new("David")
p david.greeting
# => "Hello David"
mike = Person.new("Mike")
p mike.greeting
# => "Hello Mike"

Resources