Ruby全局变量是否等同于Class Object上的类变量?

时间:2017-05-26 03:27:39

标签: javascript ruby-on-rails ruby oop inheritance

我仍然是网络开发的新手(好吧,所有开发),使用Ruby on Rails构建一个电子商务应用程序。我正在使用Redis进行缓存并构建一个简单的购物车(我自己,不使用宝石)。

除了Rails之外,我还使用MERN(Node,Express,Mongo,ReactJS)堆栈将一些简单的应用程序拼接在一起,以提高我的JavaScript技能。

在我的Redis初始化程序(config / initializers / redis.rb)的copy-pasta'代码中,我观察到了一些全局变量:

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

因为:JavaScript,我知道全球变量会让小耶稣哭泣或者强大的宙斯变成一个大橡树或者什么都没有,无论是什么(宗教自由等等)......

我知道JavaScript和Ruby是截然不同的动物:

1)JS:我的理解是在“外部”函数范围之外设置的变量在上下文中是全局的,并将位置存储到指定的值。

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

3)Ruby中的“Everything”是一个对象(数组中的块和单个索引项除外),包括类,基元等。

4)Ruby类,如果它没有从任何其他类显式继承,则继承自Object Class。

5)Rails应用程序的'config / initialize'目录包含Rails应用程序实例应该(等待它)初始化的文件:

查看我的config / initializers / redis.rb文件(上面包含的代码),上下文不明确(即没有类/模块/等)。

因此...

6)config / environment.rb包含以下代码:

# Load the Rails application.
require_relative 'application'

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

7)config / application.rb包含:

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)根据相应的Rails指南:
  http://guides.rubyonrails.org/initialization.html#config-application

Rails.application.initialize!

这个(等待它)“初始化”Rails应用程序对象的一个​​实例。

9)Rails.application对象是Class Application(???)的实例

感谢您的时间;鉴于上述情况,以下是我的问题:

A)Rails.application对象实际上是Application Class的一个实例吗?

B)这是我原来的问题,我把上面的问题包括在内,因为我觉得这个简单的问题,没有任何背景,可能看起来模糊或不清楚:

Ruby全局变量之间有什么区别:

$var = "A Ruby global variable"

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

我无法在任何地方找到这个确切的问题,如果我错过了什么,我道歉。

这些功能等同物,如果不是精确的等价物吗?

Class Object,作为所有其他类/对象最终继承的类,因此,Ruby的“全局”上下文(或者不是,我错过了一些巨大的东西)?

C)(作为编辑添加)因为全局变量需要启动并且在全局范围内可用,所以它是一个类变量而不是实例变量。那个推理听起来不错?

假设我认为全局变量和类变量(至少)在功能上是等价的,这是正确的,全局变量“无处不在”,因为“所有”都继承自类对象。

D)在考虑了第一条评论之后,这可能在鸡/蛋范例中得到了更好的表达?

如果全局变量是一个对象,它必须从Class Object继承,对吧?这意味着“全局”上下文仍然包含在Class Object中。

#RESIST

2 个答案:

答案 0 :(得分:2)

  

Ruby全局变量是否等同于Class Object上的类变量?

没有

$x = "hello"

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

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

这些功能等同物,如果不是精确的等价物吗?

没有

$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并未用于红宝石 - 它们被认为是一种设计缺陷。 $ variables很少使用。关键变量类型是:

x       => local variable
@x      => instance variable

还有一些被称为类实例的变量,这是rubyists用于类变量的变量。您可以通过在任何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:我的理解是变量设置在&#34;外部&#34;   函数的范围在上下文中是全局的并且存储位置   分配值。

它们成为window对象的属性。

  

Ruby类,如果它没有显式继承任何其他类   类,继承自Object Class。

所有ruby对象都从Object继承 - 即使它们从另一个类继承:

class Object
  def greet
    puts 'hello'
  end
end


class Animal
end

class Dog < Animal
end

Dog.new.greet

--output:--
hello
  

A)Rails.application对象实际上是一个实例   申请类?

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

但是这个全局变量也是一个对象。因此,事实上:$ var =   &#34;一个全局变量&#34;来自Class Object ...对吗?

ruby​​中没有变量是对象。

  

我对网络开发还是比较新的(好吧,所有开发)

Rails使用了很多黑魔法,以及&#34;黑魔法&#34;是一个中级到高级ruby主题。你没有说明你在红宝石学习中的位置,但如果你想了解你可以用红宝石做的野生东西,你应该阅读&#34; Metaprogramming Ruby&#34;。

答案 1 :(得分:2)

  

1)JS:我的理解是在“外部”函数范围之外设置的变量在上下文中是全局的

这取决于“变量”对完全的含义。使用constlet声明的变量是词法范围的。

在顶级上下文中用var声明的变量实际上根本不是变量,它们成为顶级对象的属性(例如windowdocument,{{ 1}},...取决于您的环境。)

  

并将位置存储到指定的值。

对于Ruby和ECMAScript中的所有变量以及ECMAScript中的属性都是如此。

  

3)Ruby中的“Everything”是一个对象(数组中的块和单个索引项除外),包括类,基元等。

这个真的取决于你对“一切”的确切含义。在Ruby中有许多“对象”(在“我们可以谈论的事物”的意义上),它们不是“对象”(在“我们可以分配给变量,传递,在Ruby代码中操作”的意义上) )。例如,变量不是Ruby中的对象。

  

A)Rails.application对象实际上是Application Class的一个实例吗?

我不知道这与全局变量有什么关系。

  

Ruby全局变量之间有什么区别:

global
     

$var = "A Ruby global variable"

是的,在他们的祖先链中没有Class Object @@var = "A class variable set on the Class Object" end 的对象和类将无法访问Object的类变量,这是非常明显的区别:

Object
  

Class Object,作为所有其他类/对象最终继承的类,因此,Ruby的“全局”上下文(或者不是,我错过了一些巨大的东西)?

class BasicObject @@var end # NameError: uninitialized class variable @@var in BasicObject 类充当某种东西的一种全局上下文,但这不是因为它是全局的,而是因为它是大多数类的父类(基本上任何不直接扩展的类)来自Object)。

任何使用继承(类变量,方法和常量)并在BasicObject中定义的内容也将在Object的所有内容中提供。但这与“全球”无关。这就是继承的工作原理。请注意,Object本身继承自ObjectKernel,因此对于这两者中定义的任何内容都是如此。

  

C)(作为编辑添加)因为全局变量需要启动并且在全局范围内可用,所以它是一个类变量而不是实例变量。那个推理听起来不错?

不,不是。全局变量既不是实例变量也不是类变量。这是一个全局变量。

  

如果全局变量是一个对象,它必须从Class Object继承,对吧?这意味着“全局”上下文仍然包含在Class Object中。

变量不是Ruby中的对象。