Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a program that looks like:

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

the use of $offset seems a bit weird.

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

Are there better ways to write the code above? The use of $offset may seem a bit ugly at first.


Update: I can put this offset inside a class definition, but what if two or several classes need to use this constant? In this case do I still need to define an $offset?

like image 218
nonopolarity Avatar asked Jun 25 '09 06:06

nonopolarity


People also ask

How do you use a global variable in Ruby?

Global Variable has global scope and accessible from anywhere in the program. Assigning to global variables from any point in the program has global implications. Global variable are always prefixed with a dollar sign ($).

Are constants global in Ruby?

Although constants look like local variables with capital letters, they have the visibility of global variables: they can be used anywhere in a Ruby program without regard to scope.


2 Answers

Variable scope in Ruby is controlled by sigils to some degree. Variables starting with $ are global, variables with @ are instance variables, @@ means class variables, and names starting with a capital letter are constants. All other variables are locals. When you open a class or method, that's a new scope, and locals available in the previous scope aren't available.

I generally prefer to avoid creating global variables. There are two techniques that generally achieve the same purpose that I consider cleaner:

  1. Create a constant in a module. So in this case, you would put all the classes that need the offset in the module Foo and create a constant Offset, so then all the classes could access Foo::Offset.

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

like image 97
Chuck Avatar answered Sep 27 '22 18:09

Chuck


One thing you need to realize is in Ruby everything is an object. Given that, if you don't define your methods within Module or Class, Ruby will put it within the Object class. So, your code will be local to the Object scope.

A typical approach on Object Oriented Programming is encapsulate all logic within 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.

like image 29
Igor Avatar answered Sep 27 '22 20:09

Igor