Ruby 在多个对象之间共享一个变量

Ruby 在多个对象之间共享一个变量,ruby,Ruby,我希望最后三种方法都能返回“Woof”。但是,此代码将调用一个未定义的变量dog\u generic错误。这似乎是因为即使是全局变量也不能用于对象。如果我将dog\u generic的所有实例都更改为@@dog\u generic,它会工作,但是@@variables很少使用,仅基于此,我就忍不住认为我做得不对 如何在多个对象之间共享一个变量 不,我不想把一串“Woof”作为参数传递给每个对象 通常,人们会使用继承来提供这种行为: class Collie def speak

我希望最后三种方法都能返回“Woof”。但是,此代码将调用一个未定义的变量dog\u generic错误。这似乎是因为即使是全局变量也不能用于对象。如果我将
dog\u generic
的所有实例都更改为
@@dog\u generic
,它会工作,但是
@@variables
很少使用,仅基于此,我就忍不住认为我做得不对

如何在多个对象之间共享一个变量


不,我不想把一串“Woof”作为参数传递给每个对象

通常,人们会使用继承来提供这种行为:

class Collie
    def speak
        puts dog_generic
    end
end

class Greyhound
    def speak
        puts dog_generic
    end
end

class Labrador 
    def speak
        puts dog_generic
    end
end

dog_generic = "Woof" 

chep = Collie.new
wrex = Collie.new
speedy = Greyhound.new
faithful = Labrador.new

chep.speak #=> Woof
wrex.speak #=> Woof
speedy.speak #=> Woof
faithful.speak #=> Woof
类狗
def发言
放“纬”
终止
终止
牧羊犬
#这里的柯利犬有什么特别的行为
终止
新牧羊犬
切普说话#=>汪汪

通常,人们会使用继承来提供这种行为:

class Collie
    def speak
        puts dog_generic
    end
end

class Greyhound
    def speak
        puts dog_generic
    end
end

class Labrador 
    def speak
        puts dog_generic
    end
end

dog_generic = "Woof" 

chep = Collie.new
wrex = Collie.new
speedy = Greyhound.new
faithful = Labrador.new

chep.speak #=> Woof
wrex.speak #=> Woof
speedy.speak #=> Woof
faithful.speak #=> Woof
类狗
def发言
放“纬”
终止
终止
牧羊犬
#这里的柯利犬有什么特别的行为
终止
新牧羊犬
切普说话#=>汪汪

您似乎对ruby中的全局变量有些困惑。您必须使用$sigil,a la显式地使它们全球化

class Dog
    def speak
        puts "Woof"
    end
end

class Collie < Dog
   # whatever behavior that is specific to Collie here
end

chep = Collie.new
chep.speak #=> Woof


这就是说,在这里,使用一个全球性的方法可能是你最糟糕的方法。定义一个泛型dog类并让您的特定类型继承,或者创建一个dog mixin并包含它都是更好的解决方案。

对于ruby中的全局变量是什么,您似乎有些困惑。您必须使用$sigil,a la显式地使它们全球化

class Dog
    def speak
        puts "Woof"
    end
end

class Collie < Dog
   # whatever behavior that is specific to Collie here
end

chep = Collie.new
chep.speak #=> Woof


这就是说,在这里,使用一个全球性的方法可能是你最糟糕的方法。定义一个泛型dog类并让您的特定类型继承,或者创建一个dog mixin并包含它,这两者都是更好的解决方案。任何以大写字母开头的变量都是常量。包括类,因此可以全局地确定常量的作用域<代码>类Foo;end是一个指向类的常量,您也可以将其写成
Foo=class.new

def speak
    puts $dog_generic
end
我同意@perimosocordiae,您可能应该使用继承。虽然我不同意他使用类来继承。Ruby中的模块包含在继承链中,但是,它们没有构造函数(您可以将它们视为抽象类,但可以继承多个模块)


做一个常数。任何以大写字母开头的变量都是常量。包括类,因此可以全局地确定常量的作用域<代码>类Foo;end是一个指向类的常量,您也可以将其写成
Foo=class.new

def speak
    puts $dog_generic
end
我同意@perimosocordiae,您可能应该使用继承。虽然我不同意他使用类来继承。Ruby中的模块包含在继承链中,但是,它们没有构造函数(您可以将它们视为抽象类,但可以继承多个模块)


当其他人回答您关于子类化
Dog
的问题时,我想向您介绍一种更好的命名实例的方法:
NameMagic
。在命令行中键入
gem install y_support
,并通过以下方式要求
NameMagic
it:

module Speach
  WOOF = "Woof"
  QUACK = "Quack"

  module Dog
    def speak
      puts WOOF
    end
  end

  module Duck
    def speak
      puts QUACK
    end
  end
end

class Collie
  include Speach::Dog
end

class Greyhound
  include Speach::Dog

  # can overwrite ancestor
  def speak
    puts "Ruff"
  end
end

class Mallard
  include Speach::Duck
end

Collie.new.speak    # => "Woof"
Greyhound.new.speak # => "Ruff"
Mallard.new.speak   # => "Quack"
然后:

require 'y_support/name_magic'
class Dog
  include NameMagic
  def speak
    puts "Woof"
  end
end

Collie = Class.new Dog
Greyhound = Class.new Dog
Labrador = Class.new Dog

Chep = Collie.new
Wrex = Collie.new
Speedy = Greyhound.new
Faithful = Labrador.new
然后:

require 'y_support/name_magic'
class Dog
  include NameMagic
  def speak
    puts "Woof"
  end
end

Collie = Class.new Dog
Greyhound = Class.new Dog
Labrador = Class.new Dog

Chep = Collie.new
Wrex = Collie.new
Speedy = Greyhound.new
Faithful = Labrador.new
NameMagic
还允许您查询实例及其名称:

Dog.instances.each &:speak
#=> Woof
#=> Woof
#=> Woof
#=> Woof
Dog.instances
#=> [#, #, #, #]
牧羊犬
#=> [#, #]
拉布拉多犬
#=> [#]
狗的名字
#=>[:Chep,:Wrex,:Speedy,:忠实]
柯利犬的名字
#=>[:Chep,:Wrex]

当其他人回答您关于子类化
狗的问题时,我想向您介绍一种更好的命名实例的方法:
NameMagic
。在命令行中键入
gem install y_support
,并通过以下方式要求
NameMagic
it:

module Speach
  WOOF = "Woof"
  QUACK = "Quack"

  module Dog
    def speak
      puts WOOF
    end
  end

  module Duck
    def speak
      puts QUACK
    end
  end
end

class Collie
  include Speach::Dog
end

class Greyhound
  include Speach::Dog

  # can overwrite ancestor
  def speak
    puts "Ruff"
  end
end

class Mallard
  include Speach::Duck
end

Collie.new.speak    # => "Woof"
Greyhound.new.speak # => "Ruff"
Mallard.new.speak   # => "Quack"
然后:

require 'y_support/name_magic'
class Dog
  include NameMagic
  def speak
    puts "Woof"
  end
end

Collie = Class.new Dog
Greyhound = Class.new Dog
Labrador = Class.new Dog

Chep = Collie.new
Wrex = Collie.new
Speedy = Greyhound.new
Faithful = Labrador.new
然后:

require 'y_support/name_magic'
class Dog
  include NameMagic
  def speak
    puts "Woof"
  end
end

Collie = Class.new Dog
Greyhound = Class.new Dog
Labrador = Class.new Dog

Chep = Collie.new
Wrex = Collie.new
Speedy = Greyhound.new
Faithful = Labrador.new
NameMagic
还允许您查询实例及其名称:

Dog.instances.each &:speak
#=> Woof
#=> Woof
#=> Woof
#=> Woof
Dog.instances
#=> [#, #, #, #]
牧羊犬
#=> [#, #]
拉布拉多犬
#=> [#]
狗的名字
#=>[:Chep,:Wrex,:Speedy,:忠实]
柯利犬的名字
#=>[:Chep,:Wrex]

如果我在PHP中这样做,我会创建一个名为
Dog
的类,包含我的变量
Dog\u generic
和方法
speak
,然后我会创建继承自
Dog
Collie
Greyhound
Labrador
的新类。很抱歉,我不知道如何在Ruby中实现这一点,但我希望它能给你一个线索。如果你在
dog\u generic
的所有实例前加上一个美元符号,比如so
$dog\u generic
,你就会得到想要的行为。不过,使用继承是一种更好的方法,根据perimosocordiae的回答,您只需创建一个常量,
DOG\u GENERIC=“Woof”
。多个对象之间不共享一个变量。变量是私有的,它们属于对象实例。你要做的是在拥有变量的对象上定义一个getter和setter方法,然后询问,或者更好的是,告诉变量的所有者你想对变量内容做什么。如果我在PHP中这样做,我会创建一个名为
Dog
的类,其中包含我的变量
Dog\u generic
和方法
speak
,然后我会创建新的
牧羊犬
灰狗
拉布拉多犬
类,它们继承自
。很抱歉,我不知道如何在Ruby中实现这一点,但我希望它能给你一个线索。如果你在
dog\u generic
的所有实例前加上一个美元符号,比如so
$dog\u generic
,你就会得到想要的行为。不过,使用继承是一种更好的方法,根据perimosocordiae的回答,您只需创建一个常量,
DOG\u GENERIC=“Woof”
。多个对象之间不共享一个变量。变量是私有的,它们是