fddd 发表于 2013-12-11 10:18:41

rails从4.0.2降到3.2.9

初学ruby和rails,想和教程同步,把rails的版本降下来。从4.0.2降到3.2.9

$ rails -v
Rails 4.0.2
尝试了 sudo gem uninstall rails,告诉我的结果是:

$ sudo gem uninstall rails
Successfully uninstalled rails-4.0.2
重新rails -v结果还是 4.0.2。

于是重新装个3.9.2吧

$ sudo gem install rails -v 3.9.2

下载完成之后依旧是4.0.2的版本

想个办法把版本替换掉就好了,先看看rails指令的路径

$ whereis rails

rails: /usr/local/bin/rails

打开这个文件 /usr/local/bin/rails

load Gem.bin_path('railties', 'rails', version)
最后一句话就是调用启动脚本的。于是去gem中找到这个方法。

在 /usr/local/lib/ruby/1.9.1/rubygems.rb 中


def self.bin_path(name, exec_name = nil, *requirements)

...
    specs = Gem::Dependency.new(name, requirements).matching_specs(true)

...
    unless spec = specs.last
      msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
      raise Gem::GemNotFoundException, msg
    end

    spec.bin_file exec_name
end

specs = Gem::Dependency.new(name, requirements).matching_specs(true) 这一步获得了地址
于是去到 Dependency中
/usr/local/lib/ruby/1.9.1/rubygems/dependency.rb

def matching_specs platform_only = false
    matches = Gem::Specification.find_all { |spec|
      self.name === spec.name and # TODO: == instead of ===
      requirement.satisfied_by? spec.version
    }
...

    matches = matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
end

可以看到是Gem::Specification.find_all 中找到了对应的路径

于是去Specification中

/usr/local/lib/ruby/1.9.1/rubygems/specification.rb

调用的是Gem::Specification.find_all,想着Gem::Specification应该是 extend Enumerable了,于是去找了def each


def self.each
    return enum_for(:each) unless block_given?

    self._all.each do |x|
      yield x
    end
end

看来一切都在 self._all里面了。


def self._all # :nodoc:
    unless defined?(@@all) && @@all then
      specs = {}

      self.dirs.each { |dir|
      Dir.each { |path|
          spec = Gem::Specification.load path.untaint
          # #load returns nil if the spec is bad, so we just ignore
          # it at this stage
          specs ||= spec if spec
      }
      }

      @@all = specs.values

      _resort!
    end
    @@all
end

果然 是从 self.dirs 中获得的路径,在self.dirs中

def self.dirs
    @@dirs ||= Gem.path.collect { |dir|
      File.join dir, "specifications"
    }
end
dirs 是通过Gem.path和“specifications” 组合之后获得的路径

输出了一下Gem.path 可以得到

["/usr/local/lib/ruby/gems/1.9.1","/home/username/.gem/ruby/1.9.1"]

所以最终的路径在"/usr/local/lib/ruby/gems/1.9.1/specifications","/home/username/.gem/ruby/1.9.1/specifications"中

第二个路径是空的。只能在第一个路径中,在第一个路径中发现存在

railties-4.0.2.gemspecrailties-3.2.9.gemspec

把第一个改成railties-4.0.2.gemspec.bak之后,在rails -v 就可以看到改成了想要的版本。如果想用4.0.2的版本,把名字改回来就好了。





总的来说呢,很简单。

1. sudo gem install rails -v 3.2.9

2. 去"/usr/local/lib/ruby/gems/1.9.1/specifications"或"/home/username/.gem/ruby/1.9.1/specifications"中,
    将railties-4.0.2.gemspec 改成railties-4.0.2.gemspec.bak

这是一个指标不治本的方法,只是改变了rails指令的调用路径而已,并没有将4.0.2版本删掉

cmkzjw 发表于 2013-12-15 08:31:50

我会好好的活。活出个样子。要你们所说的话付出代价。

359025439 发表于 2013-12-17 22:25:31

爱情像天平,当你跳下去的时候,我会摔的更痛

24cun_cn 发表于 2013-12-20 15:22:01

个性签名:我把你放在我手心最深处、你却感受不到

火冰狐 发表于 2013-12-20 23:18:32

你说,让我当做你重没出现过. 我笑了.笑的是那么的苦,

sinaren 发表于 2013-12-21 02:24:24

就想电视剧一样,电视演的东西往往和现实总是相反的。

lanxi256 发表于 2013-12-21 20:48:06

______∶如果没有失去、我们怎样学会去珍惜
页: [1]
查看完整版本: rails从4.0.2降到3.2.9