如何使用实例变量完成相同的任务?

时间:2021-11-27 23:08:07

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"]