Is a Ruby global variable equivalent to a class variable of a class object?

I'm still pretty new to web development (well, development in general), building an e-commerce app with Ruby on Rails for my portfolio. I am using Redis for caching and creating a simple shopping cart (I am not using a gem myself).

In addition to Rails, I have also put together some simple applications using the MERN stack (Node, Express, Mongo, ReactJS) to improve my JavaScript skills.

While copy-pasting the code for my Redis initializer (config / initializers / redis.rb), I observed some global variables:

if Rails.env.production?
  $redis = Redis.new(url: ENV["REDIS_URL"])
else
  $redis = Redis.new(:host => 'localhost', :port => 6379)
end

      

Because: JavaScript, I know that globals make Baby Jesus cry, or Mighty Zeus gets very rubbery, or nothing, whatever (freedom from religion, etc) ...

I know JavaScript and Ruby are completely different animals:

1) JS: As far as I understand, variables set outside the scope of the "outer" function are global in context and store the location with the assigned value.

2) Ruby: $ global_variable, @@ class_variable, @instance_variable

3) "Everything" in Ruby is an object (except for blocks and individual index elements in an array), including classes, primitives, etc.

4) A Ruby class, if it does not explicitly inherit from any other class, inherits from the object class.

5) The 'config / initialize' directory of the Rails application contains the files that the Rails application instance must initialize:

Looking at my config / initializers / redis.rb file (code above) the context is not explicit (i.e. no class / module / etc).

So that...

6) config / environment.rb contains this code:

# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!

      

7) config / application.rb contains:

require_relative 'boot'
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Ecom
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those 
specified here.
    # Application configuration should go into files in 
config/initializers
    # -- all .rb files in that directory are automatically loaded.
    config.cache_store = :redis_store, 
"redis://localhost:6379/0/cache", { expires_in: 90.minutes }
  end
end

      

8) According to the relevant Rail Guide:
http://guides.rubyonrails.org/initialization.html#config-application

Rails.application.initialize!

      

This (wait) initializes an instance of the Rails app object.

9) Rails.application object is an instance of Class Application (???)

Thank you for your time; given the above, here are my questions:

A) Is the Rails.application object actually an instance of the application class?

B) This was my original question, I included the above because I felt that this simple question without any context might seem vague or unclear:

Is there a difference between the Ruby global variable:

$var = "A Ruby global variable"

      

and

Class Object
  @@var = "A class variable set on the Class Object"
end

      

I couldn't find this exact question anywhere, my apologies if I missed something.

Are these functional equivalents, if not exact equivalents?

Is Class Object like a Class from which all other Classes / Objects ultimately inherit, hence Ruby's "global" context (or not, and I missed something huge)?

C) (added as edit) Since the global variable needs to be initialized and available in the global scope, this is a class variable, not an instance variable. Does this reasoning sound?

Assuming I'm correct in assuming that globals and class variables are (at least) functionally equivalent, globals are available "everywhere" because "everything" inherits from Class Object.

D) After considering the first comment, could all of this be better expressed in the chicken / egg paradigm?

If a global variable is an object, it must inherit from Class Object, right? This will mean that the "global" context is still wrapped in the Class Object.

+4


source to share


2 answers


1) JS: My understanding is that variables set outside the scope of the "outer" function are global in context

It depends on what exactly you mean by "variables". Variables declared with const

or let

are lexically restricted.

Variables declared via var

the higher level context, generally are not variables, they become properties of the top-level object (e.g., window

, document

, global

, ... depending on your environment).

and save space for the assigned value.

This is true for all variables in Ruby and ECMAScript, as well as properties in ECMAScript.

3) "Everything" in Ruby is an object (except for blocks and individual index elements in an array), including classes, primitives, etc.

It really depends on what you mean by "everything". There are many "objects" in Ruby (in the sense of "things we can talk about") that are not "objects" (in the sense of "things that we can assign to variables, jump around, manipulate in Ruby code")). For example, variables are not objects in Ruby.

A) Is the Rails.application object actually an instance of the application class?

I don't know what it has to do with globals.

Is there a difference between the Ruby global variable:

$var = "A Ruby global variable"

      

and

Class Object
  @@var = "A class variable set on the Class Object"
end

      



Yes, there is a rather obvious difference in that objects and classes that do not have Object

ancestors in their chain will not have access to class variables Object

:

class BasicObject
  @@var
end
# NameError: uninitialized class variable @@var in BasicObject

      

Is Class Object like the class that all other classes / objects ultimately inherit from, hence the "global" Ruby context (or not, and I was missing something huge)?

The class Object

acts as a kind of global context for some things, but this is not because it is global, but rather because it is the parent of most classes (basically anything that does not extend directly from BasicObject

).

Anything that uses inheritance (class variables, methods, and constants) and is defined in Object

will also be available in everything that comes from Object

. But this has nothing to do with "global". This is how inheritance works. Note that Object

itself inherits from Kernel

and BasicObject

, so this is true for everything that is defined in these two.

C) (added as edit). Since the global variable must be initialized and accessible in the global scope, it is a class variable, not an instance variable. Is this a reasonable sound?

No, it is not. A global variable is neither an instance variable nor a class variable. This is a global variable.

If a global variable is an object, it must inherit from the class object, right? This would mean that the "global" context is still wrapped in a class object.

Variables are not objects in Ruby.

+2


source


Is a Ruby global variable equivalent to Object class variable?

<Not p> No:
$x = "hello"

class Object 
  @@y = "goodbye"
  p class_variables
end

--output:--
[:@@y]

      

Are these functional equivalents, if not exact equivalents?

<Not p> No:
$x = 'hello'

class Animal
  @@y =  'goodbye'
end

class Dog < Animal
  def show
    puts $x
    puts @@y
  end
end

Dog.new.show

class BasketBall
  def show
    puts $x
    puts @@y
  end
end

BasketBall.new.show

--output:--
hello
goodbye
hello

1.rb:19:in `show': uninitialized class variable @@y in BasketBall (NameError)
    from 1.rb:24:in `<main>'

      

@@ variables

not used in ruby ​​- they are considered a design flaw. $ variables

rarely used. The key variables are:

x       => local variable
@x      => instance variable

      

There is also what is known as a class instance variable, which Rubyists use for class variables. You create a class instance variable by assigning it outside of any defs:

class Animal
  class <<self
    attr_accessor :x
  end

  @x =  'animal'   #<******* class instance variable *********
end

class Dog < Animal
  def show
    puts Animal.x
  end
end

d1 = Dog.new
d1.show   #=>animal
d2 = Dog.new
d2.show   #=>animal

Animal.x = 'rock'

d1.show  #=>rock
d2.show  #=>rock

      

1) JS: My understanding is that variables set outside of "external" functions are global in context and store the location for the assigned value.

They become properties of the object window

.



A Ruby class, if it does not explicitly inherit from any other Class, inherits from an object class.

All ruby ​​objects inherit from Object - even if they inherit from another class:

class Object
  def greet
    puts 'hello'
  end
end


class Animal
end

class Dog < Animal
end

Dog.new.greet

--output:--
hello

      

A) Is the Rails.application object actually an instance of the Application Class?

> $ rails c
Loading development environment (Rails 4.2.7)
2.3.0 :001 > x = Rails.application
...
...
2.3.0 :002 > x.class
 => Test4::Application 

      

But this global variable is also an object. Ergo, ipso facto: $ var = "global variable" derives from Object class ... Right?

No variable in ruby ​​is an object.

I'm still pretty new to web development (well, all development)

Rails uses a lot of black magic, and black magic is an intermediate and advanced ruby ​​theme. You haven't said where you are in your ruby ​​training, but if you want to learn about the wild things you can do with a ruby, you should read Metaprogramming Rubies.

+2


source







All Articles