我是Ruby和程序设计的新手。
要初始化类实例,我将执行以下操作:
ben_smith = Client.new("Ben Smith")
根据需要,我将调用实例引用(不确定“引用”是否正确):
ben_smith
=> #<Client:0x007fca2f630de8 @name="Ben Smith">
我目前正在学习Has-Many对象关系,并编写了一种方法,以允许“ Freelancer”类的类实例创建“ Client”类的另一个类实例。
问题在于创建了Client实例,但我不知道如何独立于“ freelancer_1”实例来访问它们。
class Client
attr_accessor :name, :company, :freelancer
def initialize(name, company)
@name = name
@company = company
end
end
class Freelancer
attr_accessor :name, :skill, :years_of_experience
def initialize(name, skill, years_of_experience)
@name = name
@years_of_experience = years_of_experience
@skill = skill
@clients = []
end
def add_client_by_name(name, company)
client = Client.new(name, company)
@clients << client
client.freelancer = self
end
def clients
@clients
end
end
这是我的种子代码:
freelancer_1 = Freelancer.new("Bobby", "Plumber", 10)
freelancer_1.add_client_by_name("Howard Rose", "TNP")
freelancer_1.add_client_by_name("Antony Adel", "Realmless")
freelancer_1.add_client_by_name("Luke Tiller", "SKY")
我想像这样访问“客户端”:
luke_tiller.company
但是似乎没有可用的“ luke_tiller”参考。 我可以通过freelancer_1访问客户端:
freelancer_1.clients[2]
我真的不确定
道歉的基本问题和我相当长的帖子。 预先感谢您提供的任何帮助。
答案 0 :(得分:1)
您可以在Freelancer
类中添加一个新方法,而不是基于索引的访问:
class Freelancer
def find_client_by_name(name)
@clients.find { |client| client.name == name }
end
end
现在您可以:
luke_tiller = freelancer_1.find_client_by_name('Luke Tiller')
puts luke_tiller.company
# SKY
答案 1 :(得分:0)
这是一种“建筑”解决方案,以防万一问题中嵌入了xy Problem。
数据结构对Array
和@clients
使用@freelancers
。它提供add_freelancer
和add_client
,以便可以将@clients
和@freelancers
的数据类型更改为文件或数据库,而不会影响Client
或{ {1}}。
Freelancer
class MyDataStore
attr_accessor :clients, :freelancers
def initialize()
@clients = Array.new
@freelancers = Array.new
end
# hide @freelancers implementation details
def add_freelancer(f)
@freelancers.push(f)
end
# hide @clients implementation details
def add_client(c)
@clients.push(c)
end
end
方法现在需要一个initialize
对象(名为“ db”)。新创建的MyDataStore
对象在初始化期间被添加到Freelancer
。
db
我们正在考虑,为什么不呢?
class Freelancer
attr_reader :name, :db, :skills, :clients
def initialize(name,db) # db is a new argument
@name = name
@skills = Array.new
@clients = Array.new
db.add_freelancer(self) # the new Freelancer is added to db
end
代码的简单应用。不用自己命名每个对象,我们只存储对象。在大多数情况下,这就是我们想要的创作。
#abstract over implementation
def add_skill(skill)
@skills.push(skill)
end
def add_client(client)
@clients.push(client)
end
end
交互式
请注意,db = MyDataStore.new
Freelancer.new('a', db)
Freelancer.new('b', db)
Freelancer.new('c', db)
Freelancer.new('d', db)
Freelancer.new('a', db)
是对象的集合。每个对象都由其哈希唯一标识。有两个名为“ a”的自由职业者,(尚未)这不是问题。
db.freelancers
警告:此代码取决于实现细节。这可能是隐藏的
Irb(main):10:0> db.freelancers
=> [#<Freelancer:0x00000001b1dd38 @clients=[], @name="a", @skills=[]>,
#<Freelancer:0x00000001b1dc98 @clients=[], @name="b", @skills=[]>,
#<Freelancer:0x00000001b1db30 @clients=[], @name="c", @skills=[]>,
#<Freelancer:0x00000001b1d9f0 @clients=[], @name="d", @skills=[]>,
#<Freelancer:0x00000001b1c988 @clients=[], @name="a", @skills=[]>]
警告:此代码依赖于实现细节。它还假定已经实现了irb(main):907:0> db.freelancers.select {|f| f.name == 'a'}
=> [#<Freelancer:0x00000001b1dd38 @clients=[], @name="a", @skills=[]>,
#<Freelancer:0x00000001b1c988 @clients=[], @name="a", @skills=[]>]
类。
Client
值得强调的是我们一直在存储和传递对象,并避免在可能的情况下将对象分配给变量。当无法避免将对象分配给变量时,我们尝试临时在一个块中进行操作,例如# add @skill 'Ruby' to freelancer named 'b'
irb(main):10:0> db.freelancers.select {|f| f.name == 'b'}[0].add_skill('Ruby')
=> ["Ruby"]
# check freelancer named 'b' has skill 'Ruby'
irb(main):11:0> db.freelancers.select {|f| f.name == 'b'}
=> [#<Freelancer:0x00000001f16e58 @clients=[], @name="b", @skills=["Ruby"]>]
# uses '\' to span two lines for readability here on stackoverflow
irb(main):195:0> db.freelancers.select {|f| f.name == 'b'} \
[0].add_client(Client.new('Best Client', db))
=> [#<Client:0x00000001ed9af8 @name="Best Client", @skills=[]>]
#check that 'Best Client' has been added to db.clients
irb(main):196:0> db.clients
=> [#<Client:0x00000001ed9af8 @name="Best Client", @skills=[]>]
#check that 'Best Client' has been added to freelancer named 'b'
irb(main):197:0> db.freelancers.select {|f| f.name == 'b'} [0]
=> #<Freelancer:0x00000001e096f0 @name="b",
@skills=[],
@clients=[#<Client:0x00000001ed9af8 @name="Best Client", @skills=[]>]>
。