代码之家  ›  专栏  ›  技术社区  ›  nonopolarity

如何在Ruby中使用全局变量或常量值?

  •  64
  • nonopolarity  · 技术社区  · 15 年前

    我有一个程序,看起来像:

    $offset = Point.new(100, 200);
    
    def draw(point)
      pointNew = $offset + point;
      drawAbsolute(point)
    end
    
    draw(Point.new(3, 4));
    

    使用 $offset 看起来有点奇怪。

    在C语言中,如果我定义了任何函数之外的东西,它将自动成为一个全局变量。为什么在Ruby中必须是 美元偏移 但不能 offset 还是全球化?如果是 抵消 ,那么它是本地的吗?但在当地,因为感觉非常全球化。

    有没有更好的方法来写上面的代码?使用 美元偏移 一开始看起来有点难看。


    更新:我可以把这个偏移量放在 class 定义,但如果两个或多个类需要使用这个常量呢?在这种情况下,我还需要定义 美元偏移 ?

    4 回复  |  直到 9 年前
        1
  •  53
  •   Kasama    9 年前

    你需要意识到的一件事是在Ruby中,一切都是一个对象。鉴于此,如果您不在 Module Class ,Ruby会把它放在 Object 班级。所以,您的代码将是本地的 对象 范围。

    面向对象编程的典型方法是将所有逻辑封装在一个类中:

    class Point
      attr_accessor :x, :y
    
      # If we don't specify coordinates, we start at 0.
      def initialize(x = 0, y = 0)
        # Notice that `@` indicates instance variables.
        @x = x
        @y = y
      end
    
      # Here we override the `+' operator.
      def +(point)
        Point.new(self.x + point.x, self.y + point.y)
      end
    
      # Here we draw the point.
      def draw(offset = nil)
        if offset.nil?
          new_point = self
        else
          new_point = self + offset 
        end
        new_point.draw_absolute
      end
    
      def draw_absolute
        puts "x: #{self.x}, y: #{self.y}"
      end
    end
    
    first_point = Point.new(100, 200)
    second_point = Point.new(3, 4)
    
    second_point.draw(first_point)
    

    希望这能澄清一点。

        2
  •  109
  •   Chuck    15 年前

    Ruby中的变量范围在某种程度上由sigils控制。变量以开头 $ 是全局的,变量 @ 是实例变量, @@ 表示类变量,以大写字母开头的名称是常量。所有其他变量都是局部变量。当您打开一个类或方法时,这是一个新的作用域,前一个作用域中可用的局部变量不可用。

    我通常喜欢避免创建全局变量。有两种技术通常达到我认为更清洁的目的:

    1. 在模块中创建常量。所以在本例中,您将把所有需要偏移量的类放在模块中 Foo 并创建一个常量 Offset ,这样所有类都可以访问 Foo::Offset .

    2. 定义访问值的方法。您可以全局定义该方法,但我还是认为最好将其封装到模块或类中。这样,数据就可以在您需要的地方使用,您甚至可以在需要的时候修改它,但是您的程序结构和数据的所有权将更加清晰。这更符合OO设计原则。

        3
  •  9
  •   mikej heading_to_tahiti    15 年前

    全局变量需要前缀的原因之一 $ )这是因为在Ruby中,与在C中不同的是,在分配变量之前不必声明变量,因此对于给定如下语句的全局变量没有特定的前缀 offset = Point.new(100, 200) 在draw方法中,Ruby不知道您是在引用现有的变量,还是在方法中创建一个新的局部变量。与之相同 @ 实例变量的前缀。

        4
  •  -2
  •   the Tin Man    12 年前

    我认为它是您声明的偏移量的本地文件。将每个文件都视为方法本身。

    可能把整个东西放到一个类中,然后用 @@offset = Point.new(100, 200); ?