Here I use a global variable to store a list because I can't figure out how I can keep ahold of a list long enough to check its values for duplicates.
在这里,我使用全局变量来存储列表,因为我无法弄清楚如何保持列表的长度足以检查其重复值。
$list = []
def hand_out_gift(name)
if $list.include?name
puts "No present for you"
else
$list.push(name)
end
end
hand_out_gift("Peter")
hand_out_gift("Alison")
hand_out_gift("John")
hand_out_gift("Maria")
hand_out_gift("Peter")
How can I accomplish the same check with an instance variable?
如何使用实例变量完成相同的检查?
2 个解决方案
#1
0
Ruby works best when you approach your problem using object oriented code.
当您使用面向对象的代码处理问题时,Ruby效果最佳。
More often than not, you'll want to think of your data as objects with their own properties and methods, rather than as consequences of data structures that reside in the scope you're working on (global in your example, or local if you edit it per the other answer).
通常情况下,您需要将数据视为具有自己的属性和方法的对象,而不是将数据结构视为您正在处理的范围的结果(在您的示例中是全局的,或者如果您是本地的)根据其他答案编辑它)。
Here's a convoluted example to illustrate:
这是一个复杂的例子来说明:
class Party
def initialize(members = nil)
@members = {}
invite(*members) if members
end
def members
@members.values
end
def invite(*members)
members = Hash[members.map { |member|
if member.is_a?(Member)
[member.name.downcase, member]
else
[member.downcase, Member.new(member)]
end
}]
@members = members.merge(@members)
end
def find(member)
if member.is_a?(Member)
key = member.name
else
key = member
end
@members[key.downcase]
end
end
We could define a member object alongside.
我们可以在旁边定义一个成员对象。
class Member
attr_reader :name, :gift
def initialize(name)
@name = name
end
def has_gift?
!!@gift
end
def gift=(gift)
raise if has_gift?
@gift = gift
end
end
and we could call that using:
我们可以使用以下方法调用:
members = ["Peter", "Alison", "John", "Maria"]
party = Party.new(members)
party.members.each { |m| m.gift = true }
party.find("Peter").gift = :foo
(Completely untested code, so you'll hopefully forgive the potential syntax error.)
(完全未经测试的代码,所以你希望原谅潜在的语法错误。)
In the above, Party is responsible for managing (and indexing) the list of members. Members, on its end, is responsible for checking if that member got a gift or not. To each his own properties, and assorted methods.
在上文中,Party负责管理(和索引)成员列表。会员最终负责检查该会员是否收到礼物。每个他自己的属性,以及各种方法。
I could (should in fact) have used a Set object instead of a Hash in that Party object. Note how encapsulating this internal representation and never exposing it means you can later change it to a Set indeed, without any harmful effect for the rest of the code. The only change elsewhere would be the need to define how to hash a Member.
我(实际上应该)在该Party对象中使用了Set对象而不是Hash。请注意如何封装此内部表示并永远不暴露它意味着您可以稍后将其更改为Set,而不会对其余代码产生任何有害影响。其他地方唯一的变化是需要定义如何散列成员。
#2
0
The difference between a global variable
and an instance variable
is global variables
start with $
while instance variables
start with @
and global variables
are globally accessible, while instance variables are only accessible to an instance of the object
全局变量和实例变量之间的区别是全局变量以$开头,而实例变量以@开头,全局变量可全局访问,而实例变量只能访问对象的实例
@list = []
def hand_out_gift(name)
if @list.include?name
puts "No present for you"
else
@list.push(name)
end
end
hand_out_gift("Peter")
hand_out_gift("Alison")
hand_out_gift("John")
hand_out_gift("Maria")
hand_out_gift("Peter")
@list # => ["Peter", "Alison", "John", "Maria"]
#1
0
Ruby works best when you approach your problem using object oriented code.
当您使用面向对象的代码处理问题时,Ruby效果最佳。
More often than not, you'll want to think of your data as objects with their own properties and methods, rather than as consequences of data structures that reside in the scope you're working on (global in your example, or local if you edit it per the other answer).
通常情况下,您需要将数据视为具有自己的属性和方法的对象,而不是将数据结构视为您正在处理的范围的结果(在您的示例中是全局的,或者如果您是本地的)根据其他答案编辑它)。
Here's a convoluted example to illustrate:
这是一个复杂的例子来说明:
class Party
def initialize(members = nil)
@members = {}
invite(*members) if members
end
def members
@members.values
end
def invite(*members)
members = Hash[members.map { |member|
if member.is_a?(Member)
[member.name.downcase, member]
else
[member.downcase, Member.new(member)]
end
}]
@members = members.merge(@members)
end
def find(member)
if member.is_a?(Member)
key = member.name
else
key = member
end
@members[key.downcase]
end
end
We could define a member object alongside.
我们可以在旁边定义一个成员对象。
class Member
attr_reader :name, :gift
def initialize(name)
@name = name
end
def has_gift?
!!@gift
end
def gift=(gift)
raise if has_gift?
@gift = gift
end
end
and we could call that using:
我们可以使用以下方法调用:
members = ["Peter", "Alison", "John", "Maria"]
party = Party.new(members)
party.members.each { |m| m.gift = true }
party.find("Peter").gift = :foo
(Completely untested code, so you'll hopefully forgive the potential syntax error.)
(完全未经测试的代码,所以你希望原谅潜在的语法错误。)
In the above, Party is responsible for managing (and indexing) the list of members. Members, on its end, is responsible for checking if that member got a gift or not. To each his own properties, and assorted methods.
在上文中,Party负责管理(和索引)成员列表。会员最终负责检查该会员是否收到礼物。每个他自己的属性,以及各种方法。
I could (should in fact) have used a Set object instead of a Hash in that Party object. Note how encapsulating this internal representation and never exposing it means you can later change it to a Set indeed, without any harmful effect for the rest of the code. The only change elsewhere would be the need to define how to hash a Member.
我(实际上应该)在该Party对象中使用了Set对象而不是Hash。请注意如何封装此内部表示并永远不暴露它意味着您可以稍后将其更改为Set,而不会对其余代码产生任何有害影响。其他地方唯一的变化是需要定义如何散列成员。
#2
0
The difference between a global variable
and an instance variable
is global variables
start with $
while instance variables
start with @
and global variables
are globally accessible, while instance variables are only accessible to an instance of the object
全局变量和实例变量之间的区别是全局变量以$开头,而实例变量以@开头,全局变量可全局访问,而实例变量只能访问对象的实例
@list = []
def hand_out_gift(name)
if @list.include?name
puts "No present for you"
else
@list.push(name)
end
end
hand_out_gift("Peter")
hand_out_gift("Alison")
hand_out_gift("John")
hand_out_gift("Maria")
hand_out_gift("Peter")
@list # => ["Peter", "Alison", "John", "Maria"]