Console printing backwards - ruby

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

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

How to call an instance method on an instance of a class from a different class

So I have the following setup
class foo
:attr_accessor :textBoxInFoo
#textBoxInFoo
def appendText
//appends text to textBoxInFoo
end
def getLastPartOfText
//gets the last line of text in textBoxInFoo
end
end
class bar
def UseFoo
//Declares instance of textBoxInFoo
end
end
class snafu
def runInBackground
//Needs to read and write from instance of textBoxInFoo in bar class
end
end
What I'm failing to grasp is how to do what I need to do in runInBackground to get it to read and write to textBoxInFoo, I've been reading through various explanations of instance and class methods, and none of them have really clicked with me yet, so I'm wondering if anyone knows what I'm messing up.
This is a small example of how you can create a user object and send it to student object as an argument. run() method calls user's run method.
class User
attr_accessor :name
def initialize(name) # it is similar to constructor
#name = name
end
#run method
def run
puts "I am running"
end
#getter for name
def get_name
#name
end
#setter for name
def set_name=(name)
#name = name
end
end
class Student
attr_accessor :obj
def initialize(obj)
#obj = obj
end
def run
obj.run
puts "inside of Student"
end
end
user = User.new("John")
stud = Student.new(user)
stud.run # shows I am running
# inside of student

Trying to figure out what's wrong with this code

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.

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