I am trying to write some functionality which allows me to take a broken bike to a garage to have it fixed, whilst implementing this i have come across this issue. i understand that this usually is because it cannot find the file but have ran out of ideas on how to fix it. If you need any of the other code let me know but i thought this would be all the code needed.
dockingstation.rb:
require_relative 'Bike'
require_relative 'van'
require_relative 'garage'
class DockingStation
attr_reader :dock, :max_dock, :DEFAULT_CAPACITY
DEFAULT_CAPACITY = 20
def initialize(capacity = DEFAULT_CAPACITY)
#max_dock = capacity
#dock = []
end
def release_bike
if !empty?
#dock.each_with_index do |bike, index|
if bike.working?
#dock.delete_at(index)
return bike
else
raise "Bike is broken"
end
end
else
raise "No bikes to release"
end
end
def dock_bike(bike, working = true)
if !full?
#dock << bike
else
raise "Too many bikes"
end
end
def show_dock
#dock.each do |el|
return el
end
end
def van_takes_broken_bikes(van)
puts #dock
#dock.each_with_index do |bike, index|
if bike.working? == true
van.storage.append(bike)
else
van.storage.append(bike)
end
end
end
private def full?
#dock.length == #max_dock
end
private def empty?
#dock.length == 0
end
end
dock = DockingStation.new
bike = Bike.new
van = Van.new
bike.report_broken
dock.dock_bike(bike)
dock.van_takes_broken_bikes(van)
van.rb:
require_relative 'dockingstation'
require_relative 'garage'
class Van
attr_reader :storage
def initialize
#storage = []
end
def take_broken_bikes_to_garage(bikes)
end
end
I am trying to get programm started where i cant read in a csv File an it prints the data out on a pdf-File. Now i have a problem.
Heres is my Code:
------------------------------------
require_relative 'friends'
class List
attr_accessor :list_name, :list
def initialize(list_name)
#list_name = list_name
#list = []
end
def list_name
#list_name
end
def liste
#list
end
def wert(place)
#list[place].to_s
end
def list_length
#list.length
end
def print_list
#list.each do |freunde|
"#{freunde.name},#{freunde.age}"
end
end
def add_friend(a_friend)
#list.push(a_friend)
end
def load_friend(from_file)
File.readlines(from_file).each do |line|
add_friend(Freunde.from_csv(line))
end
end
end
-------------------------------------------
require_relative 'list'
class Friends
attr_accessor :name,:age
def initialize(name, age)
#name = name
#age = age
end
def self.from_csv(string)
name, age = string.split(',')
Freunde.new(name,age)
end
def friends
#name
end
end
-------------------------------------------
require 'prawn'
require_relative 'list'
require_relative 'friends'
class Generating
include Prawn::View
def initialize
#document = Prawn::Document.new(:page_size => "A4")
#fontpath = File.expand_path("../data/fonts", __FILE__)
liste1 = Listen.new("Friendslist")
liste1.load_friend("test.csv")
print_list
save
end
def print_friends
font("#{#fontpath}/Arial.ttf") do
font_size 11
text_box("#{liste1.print_list}", :at => [15,405], :height => 50,
:width => 250)
end
end
def save
self.render_file "Hello.pdf"
end
end
---------------------------------------------
When i now create a new generating-Object:
gen = Generating.new
then it fails the whole programm because the error says method unknow (print_list). Am i submitting the wrong object for the method(print_list), or am using the text output methods of prawn wrong?
print_list is an instance method of List class, and you call it on self object, which is there an instance of Generating. It should be:
liste1 = Listen.new("Friendslist")
liste1.load_friend("test.csv")
#⇓⇓⇓⇓⇓⇓
liste1.print_list
I'm learning the design patterns. How do you think is it an appropriate example of FactoryMethod pattern?
There are Unit and its subclasses: Soldier and Doctor. They can greet somehow. There are also UnitFactory, SoldierFactory and DoctorFactory. They produce according units.
class Unit
class GreetError < StandardError; end
def greet; raise GreetError; end
end
class Soldier < Unit
def greet; 'I am a soldier'; end
end
class Doctor < Unit
def greet; 'I am a doctor'; end
end
class UnitFactory
class CreateUnitError < StandardError; end
def create_unit; raise CreateUnitError; end
end
class SoldierFactory < UnitFactory
def create_unit; Soldier.new; end
end
class DoctorFactory < UnitFactory
def create_unit; Doctor.new; end
end
class Army
attr_reader :unit_factory, :count, :units
def initialize(unit_factory, count)
#unit_factory = unit_factory
#count = count
#units = []
gather
end
def gather
count.times { units << unit_factory.create_unit }
end
def greet
units.map { |unit| unit.greet }
end
end
Ok guys, I am learning ruby and I am having a little bit of trouble with the tutorial. I was wondering if you could help me out!
Take the following code:
class Dish
def initialize(name, ingred, descrip)
#name = name
#ingred = ingred
#descrip = descrip
end
def name
#name
end
def name=(new_name)
#name = new_name
end
def ingred
#ingred
end
def ingred=(new_ingred)
#ingred = new_ingred
end
def descrip
#descrip
end
def descrip=(new_descrip)
#descrip = new_descrip
end
def display
puts "I am a #{#name} and my ingredient is #{#ingred} and my description is #{descrip}"
end
end
dis1 = Dish.new('Pizza', 'sauce', 'put sauce on that thing')
dis1.display
Ok so here is my question and I hope I explain it well enough. So far I have learned to take enter one parameter when making a new instance of a class (i.e. (name, ingred, descrip)). What I am wondering is if a dish has multiple ingredients, how would I add that to my class? Also, if I wanted to count the number of ingredients or the number of names, how would I do that. I am just learning about classes and I am having trouble matching the exact wording I would Google for. Thanks!
I'll try to answer some of your questions. To simplify, I removed your variable, descrip and its associated methods. You see I've put a * in front of ingred in initialize. This means that a variable number of arguments are passed after name. This is one way of dealing with your question about having multiple ingredients. Here ingred is an array. Since #ingred is set equal to ingred, #ingred is also an array. If you look at the various methods and what some print when invoked (shown at the bottom), you should be able to see how this works. (Edited to add a bit of functionality. You may need to scroll down at the bottom.)
class Dish
def initialize(name, *ingred)
#name = name
#ingred = ingred
end
def name
#name
end
def name=(new_name)
#name = new_name
end
def ingred
#ingred
end
def ingred=(*ingred)
#ingred = ingred
end
def add_ingred(ingred)
#ingred << ingred
end
def remove_ingred(ingred)
#ingred.delete(ingred)
end
def nbr_ingred
#ingred.count
end
end
dis1 = Dish.new("Pizza", "sauce", "crust", "cheese", "anchovies")
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies"]
dis1.add_ingred("olives")
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives"]
dis1.add_ingred(["capers", "mushrooms"])
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives", ["capers", "mushrooms"]]
dis1.ingred.flatten!
p dis1.ingred #=> ["sauce", "crust", "cheese", "anchovies", "olives", "capers", "mushrooms"]
dis1.remove_ingred("anchovies")
p dis1.ingred #=> ["sauce", "crust", "cheese", "olives", "capers", "mushrooms"]
p dis1.nbr_ingred #=> 6
dis1.ingred = "olives", "pineapple" # treated as ["olives", "pineapple"]
p dis1.ingred #=> [["olives", "pineapple"]]
dis1.ingred = ["cheese", "crust"]
p dis1.ingred #=> [["olives", "pineapple"]]
dis1.ingred.flatten!
p dis1.ingred #=> ["olives", "pineapple"]
Use arrays.
class Dish
class Ingredient
attr_accessor :name, :description
def initialize(name, description)
#name = name
#description = description
end
def to_s
"#{name} - #{description}"
end
end
attr_accessor :name, :description, :ingredients
def initialize(name, description)
#name = name
#description = description
#ingredients = []
end
def to_s
"#{name} - #{description}\n #{ingredients.join("\n").to_s}"
end
end
pizza = Dish.new("Pizza", "Italian style pizza")
pizza.ingredients << Dish::Ingredient.new("Tomato Sauce", "Juicy Juicy Tomato Sauce.")
pizza.ingredients << Dish::Ingredient.new("Cheese", "Cheese, duh.")
puts pizza.to_s
As the two answers before me did both leave out the description parameter i will stealCary Swoveland's answer and add the descrip parameter:
class Dish
attr_accessor :name, :descrip
def initialize(name, *ingred, descrip) # Only in Ruby 1.9+
#name = name
#ingred = *ingred
#descrip = descrip
end
def ingred
#ingred
end
def ingred=(*ingred)
#ingred = ingred
end
def add_ingred(ingred)
#ingred << ingred
end
def remove_ingred(ingred)
#ingred.delete(ingred)
end
def nbr_ingred
#ingred.count
end
def display
puts "I am a #{#name} and my ingredient is #{#ingred.join(', ')} and my description is #{descrip}"
end
end
dis1 = Dish.new('Pizza', 'sauce', 'ham', 'put ingredients on that thing.')
dis1.add_ingred('fish')
dis1.display #=> I am a Pizza and my ingredient is sauce, ham, fish and my description is put ingredients on that thing.
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name
attr_reader attr_name + "_history"
class_eval %Q{
def #{attr_name}=(new_value)
##{attr_name}_history = [nil] if ##{attr_name}_history.nil?
##{attr_name}_history << ##{attr_name} = new_value
end
}
end
end
class Example
attr_accessor_with_history :foo
attr_accessor_with_history :bar
end
There is Class.attr_accessor_with_history method that provides the same
functionality as attr_accessor but also tracks every value the attribute has
ever had.
> a = Example.new; a.foo = 2; a.foo = "test"; a.foo_history
=> [nil, 2, "test"]
But,
> a = Example.new; a.foo_history
=> nil
and it should be [nil.
How can I define single initialize method for Example class where each
…_history value will be initialize as [nil]?
I think, your best bet is to define a custom reader for history (along with your custom writer).
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name
class_eval %Q{
def #{attr_name}_history
##{attr_name}_history || [nil] # give default value if not assigned
end
def #{attr_name}=(new_value)
##{attr_name}_history ||= [nil] # shortcut, compare to your line
##{attr_name}_history << ##{attr_name} = new_value
end
}
end
end
class Example
attr_accessor_with_history :foo
attr_accessor_with_history :bar
end
a = Example.new; a.foo = 2; a.foo = "test";
a.foo_history # => [nil, 2, "test"]
a = Example.new
a.foo_history # => [nil]
Edit:
Here's a slightly more verbose snippet, but it doesn't use class_eval (which is frowned upon, when used without necessity).
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name
define_method "#{attr_name}_history" do
instance_variable_get("##{attr_name}_history") || [nil]
end
define_method "#{attr_name}=" do |new_value|
v = instance_variable_get("##{attr_name}_history")
v ||= [nil]
v << new_value
instance_variable_set("##{attr_name}_history", v)
instance_variable_set("##{attr_name}", new_value)
end
end
end
Sloves in one class_eval
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name
attr_reader attr_name+"_history"
class_eval %Q{
def #{attr_name}=(val)
if ##{attr_name}_history
##{attr_name}_history << ##{attr_name}
else
##{attr_name}_history = [nil]
end
##{attr_name} = val
end
}
end
end