How do you use global variables or constant values ​​in Ruby?

I have a program that looks like this:

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

using $offset seems a bit odd.

In C, if I define something outside of any function, it is a global variable automatically. Why in Ruby should it be $offset , but cannot be offset and still global? If it is offset , is it local? But locally, where, because it feels very global.

Are there any better ways to write the code above? Using $offset may seem a little ugly at first.




Update: I can put this offset inside the class definition, but what if two or more classes have to use this constant? In this case, do I still need to determine $offset ?

+67
ruby global-variables
Jun 25 '09 at 6:03
source share
4 answers

One thing you need to understand in Ruby is the object. Given this, if you do not define your methods within Module or Class , Ruby will put it in the Object class. This way your code will be local to the Object scope.

A typical approach to object-oriented programming is to encapsulate all the logic inside a class:

 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) 

Hope this clarifies a bit.

+53
Jun 25 '09 at 12:10
source share

Ruby's variable region is somewhat controlled by sigils. Variables starting with $ are global, variables with @ are instance variables, @@ means class variables, and capitalized names are constants. All other variables are local. When you open a class or method, the new scope and locales available in the previous scope are not available.

I usually prefer to avoid creating global variables. There are two methods that usually achieve the same goal, which I find cleaner:

  • Create a constant in the module. Therefore, in this case, you must place all classes that require an offset in the Foo module and create an Offset constant so that all classes can access Foo::Offset .

  • Define a method to access the value. You can define a method globally, but again, I think it's better to encapsulate it in a module or class. Thus, data is available where you need it, and you can even change it if you need, but the structure of your program and ownership of the data will be clearer. This is more in line with OO design principles.

+111
Jun 26 '09 at 5:23
source share

One of the reasons a global variable needs a prefix (called a sigil) is because in Ruby, unlike C, you don't need to declare variables before assigning them. Sigil is used as a way to explicitly indicate the scope of a variable.

Without a special prefix for globals, given the pointNew = offset + point operator inside your draw method, then offset refers to a local variable inside the method (and in this case leads to a NameError ). The same for @ used to refer to instance variables and @@ for class variables.

In other languages ​​that use explicit declarations, such as C , Java , etc., Ad placement is used to control the scope.

+10
Jun 25 '09 at 7:39
source share

I think this is local to the file you declared the offset to. View each file as the method itself.

Perhaps put all this in a class, and then do the offset of the class variable with @@offset = Point.new(100, 200); ?

-3
Jun 25 '09 at 6:06
source share



All Articles