mur*_*a52 7 ruby ruby-on-rails
我是ruby和rails的新手.我看到我包含的任何宝石,我都可以直接在我的代码中使用它的功能.我没有看到代码的任何导入,也没有看到函数的任何名称空间.如果gems包含具有相同名称的函数,那么这不是冲突的配方吗?
所以 -
ruby/rails如何导入函数,如何将函数映射到gem?当2颗宝石包含相同的功能时,它会导致冲突吗?如果我想显式使用ruby库,我将如何导入其代码?红宝石中有名字空间吗?
ruby将一个文件中声明的函数导入另一个文件的方式是通过该require函数.load完成类似的事情,但出于一般目的,require通常是你想要的(更多细节见http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/)
hello_lib.rb
def say_hello
puts "hello"
end
# that's right, you can execute code when a library is required,
# so the sky's the limit of what you can do
puts "Hey, I've been required!"
Run Code Online (Sandbox Code Playgroud)
hello_caller.rb
# load the code from `hello_lib.rb` in the same directory
require './hello_lib.rb'
Run Code Online (Sandbox Code Playgroud)
子目录/ hello_other_caller.rb
# for illustrative purposes, adding the parent directory to the load path
# so that ruby will look there for files I want to require
$: << '..'
require 'hello_lib.rb'
say_hello
Run Code Online (Sandbox Code Playgroud)
Gems可以被认为是一个ruby代码包或库.有几种加载gem的方法,但最常见的是通过requireSay你已经安装了progressbargem来在终端中显示简单的进度条(gem install progressbar)
progressbar_test.rb
require 'rubygems'
require 'progressbar'
# this also works
# gem 'progressbar', '~> 0.9.2'
pbar = ProgressBar.new("test", 100)
100.times do
sleep 0.1
pbar.inc
end
pbar.finish
Run Code Online (Sandbox Code Playgroud)
这样做的原因是,当我们需要时rubygems,它会将进度条gem添加到ruby查找所需文件的路径中.
Rails只是一组宝石,其中一些提供可执行的脚本.在以前的版本中,您必须指定要加载的gem,这与我们上面的方式非常相似.但现在,bundler我们可以在一个中指定所有宝石Gemfile,以及版本控制和源信息.Bundler然后将计算出宝石之间的依赖关系并保留我们针对项目的特定版本Gemfile.lock.由于bundler它本身就是一个宝石,你经常会看到这样的代码:
配置/ application.rb中
require 'bundler'
Bundler.require(:default, Rails.env)
Run Code Online (Sandbox Code Playgroud)
此代码告诉Bundler加载我们在gemfile中平面列出的所有依赖项,以及我们在与当前rails env对应的组中列出的依赖项(例如:development).
是的,您可以通过几种方式遇到问题.两个宝石可以具有相同的名称,虽然在这种情况下它们不能被推送到rubygems,你会很快发现它.一个更微妙的命名空间问题是如果两个文件做这样的事情:
hello1.rb
def hello
puts "Hi"
end
Run Code Online (Sandbox Code Playgroud)
hello2.rb
def hello
puts "Hello, there!"
end
Run Code Online (Sandbox Code Playgroud)
hello3.rb
require './hello1'
require './hello2'
hello
Run Code Online (Sandbox Code Playgroud)
在这里,我们看到当全局命名空间中存在名称空间冲突时会发生什么.如果两个库在同一个类名中定义相同的方法,则会发生类似的事情(这种类型的猴子修补虽然不鼓励,但仍然会发生!).在实践中,您不会遇到太多问题,尤其是在使用模块命名空间代码时使用良好规则时,例如,如果我正在编写gem hello:
module Hello
# not such a good name, but won't conflict with ::Object
class Object
def to_s
puts 'this is a bad idea'
end
end
end
Run Code Online (Sandbox Code Playgroud)
Gems 是有名称空间的,因此您可以通过以下方式显式调用方法
ModuleName::Class
Run Code Online (Sandbox Code Playgroud)
如果您没有显式调用包含的类,则 ruby 将遍历其所有类,直到找到您调用的类,如果没有,则会抛出 NoMethod 错误。
为了让 Ruby 看到这个库,你需要它:
require 'some_library'
Run Code Online (Sandbox Code Playgroud)
要将库包含在类中,您:
class SomeClass
include SomeLibrary
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2231 次 |
| 最近记录: |