我正在玩一个小小的地址簿程序。我有三节课; AddressBook
,Contact
和Address
。在to_s
类中编写的Address
方法定义了地址的输出格式,我在print_addresses
类中编写了一个Contact
方法,该方法是否传入了参数是long
或short
应输出to_s方法中定义的两种输出格式之一。在print_addresses('long')
类的Contact
实例上调用AddressBook
时,它只会输出short
方法中定义的to_s
格式。
这不符合我的预期,我很确定我对方法和变量范围或显式和隐式返回的理解是错误的,但我无法辨别出错的地方。我写的代码如下,任何人都可以帮助我更好地理解这个吗?谢谢。
地址类
class Address
attr_accessor :kind, :street_1, :street_2, :city, :state, :postal_code
def to_s(format = 'short')
address = ''
case format
when 'long'
address += street_1 + "\n"
address += street_2 + "\n" if !street_2.nil?
address += "#{city}, #{state} #{postal_code}"
when 'short'
address += "#{kind}: "
address += street_1
if street_2
address += " " + street_2
end
address += ", #{city}, #{state}, #{postal_code}"
end
address
end
end
联系班级
require './phone_number'
require './address'
class Contact
attr_writer :first_name, :middle_name, :last_name
attr_reader :phone_numbers, :addresses
def initialize
@phone_numbers = []
@addresses = []
end
def add_address(kind, street_1, street_2, city, state, postal_code)
address = Address.new
address.kind = kind
address.street_1 = street_1
address.street_2 = street_2
address.city = city
address.state = state
address.postal_code = postal_code
addresses.push(address)
end
def print_addresses(format = 'short')
puts "Addresses:"
case format
when 'short'
addresses.each do |address|
address.to_s('short')
end
when 'long'
addresses.each do |address|
address.to_s('long')
end
end
end
end
AddressBook类
require './contact'
class AddressBook
attr_reader :contacts
def initialize
@contacts = []
end
def find_by_name(name)
results = []
search = name.downcase
@contacts.each do |contact|
if contact.first_name.downcase.include?(search)
results.push(contact)
end
end
puts "Name search results (#{search})"
results.each do |contact|
puts contact.to_s('full_name')
puts contact.print_addresses('long')
puts contact.print_phone_numbers
end
end
end
address_book = AddressBook.new
james = Contact.new
james.first_name = "James"
james.middle_name = "jim"
james.last_name = "jimbo"
james.add_address('home', '1', '2', '3', '4', '5')
address_book.contacts.push(james)
puts "-" * 35
puts james.print_addresses('long')
puts '=' * 35
ruby address_book.rb - 输出
------------------------------
Addresses:
home: 1, 2, 3, 4, 5
===================================
期待并试图实现:
------------------------------
Addresses:
1,
2,
3, 4, 5
===================================
答案 0 :(得分:3)
它正在做长短版本。您可以在puts "long"
函数中添加puts "short"
和to_s
来查看此内容。
问题不在于范围,而在于您依赖print_addresses
中最后一次评估表达式的隐式返回。 print_addresses
不会打印任何内容,也不会显式返回任何内容。它尽职地调用address.to_s('long')
,抛出结果,并返回最后评估的表达式的结果...... address
。然后address
运行puts
,这会导致它被转换为具有默认短格式的字符串。您可以注释掉address.to_s
的来电,您将获得相同的结果。
address
是最后一个评估表达式,这可能看起来很奇怪,这就是为什么你应该总是做一个明确的回归。它使代码更易于阅读,并为每个人节省了很多麻烦。这也指出你的函数应该返回多个东西,这是你不能轻易做到的。
def print_addresses(format = 'short')
puts "Addresses:"
formatted_addresses = []
case format
when 'short'
addresses.each do |address|
formatted_addresses << address.to_s('short')
end
when 'long'
addresses.each do |address|
formatted_addresses << address.to_s('long')
end
end
return formatted_addresses
end
作为旁注,由于print_addresses
不打印,因此应将其称为format_addresses
。它也应该摆脱冗余的案例陈述。额外格式化(“地址”标题)进入一个包装方法,使format_addresses
变得灵活。
def display_addresses(format)
return ["Addresses: "] + format_addresses(format)
end
def format_addresses(format = 'short')
formatted_addresses = []
addresses.each do |address|
formatted_addresses << address.to_s(format)
end
return formatted_addresses
end