Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

宝石はどのように機能しますか?

ほとんどの場合、RubyJustWorkのgemsです。しかし、Rubyの魔法には大きな問題があります。問題が発生した場合、その理由を見つけるのは困難です。

宝石に問題が発生することはめったにありません。しかし、そうすると、Googleは驚くほど役に立たなくなります。エラーメッセージは一般的なものであるため、さまざまな原因の1つが考えられます。 そして、gemが実際にRubyでどのように機能するかを理解していないと、これらの問題を自分でデバッグするのに苦労することになります。

宝石は見える 魔法の。しかし、少し調べれば、非常に簡単に理解できます。

gem installとは しますか?

Ruby gemは、少し余分なデータを追加したコードです。 gem unpackを使用すると、gem内のコードを確認できます。 :

~/Source/playground jweiss$ gem unpack resque_unit
Fetching: resque_unit-0.4.8.gem (100%)
Unpacked gem: '/Users/jweiss/Source/playground/resque_unit-0.4.8'
~/Source/playground jweiss$ cd resque_unit-0.4.8 
~/Source/playground/resque_unit-0.4.8 jweiss$ find .
.
./lib
./lib/resque_unit
./lib/resque_unit/assertions.rb
./lib/resque_unit/errors.rb
./lib/resque_unit/helpers.rb
./lib/resque_unit/plugin.rb
./lib/resque_unit/resque.rb
./lib/resque_unit/scheduler.rb
./lib/resque_unit/scheduler_assertions.rb
./lib/resque_unit.rb
./lib/resque_unit_scheduler.rb
./README.md
./test
./test/resque_test.rb
./test/resque_unit_scheduler_test.rb
./test/resque_unit_test.rb
./test/sample_jobs.rb
./test/test_helper.rb
~/Source/playground/resque_unit-0.4.8 jweiss$

gem install 、最も単純な形式では、このようなことを行います。 gemを取得し、そのファイルをシステムの特別なディレクトリに配置します。 gem installの場所を確認できます gem environmentを実行すると、gemがインストールされます (INSTALLATION DIRECTORY:を探してください 行):

~ jweiss$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.2.2
  - RUBY VERSION: 2.1.2 (2014-05-08 patchlevel 95) [x86_64-darwin14.0]
  - INSTALLATION DIRECTORY: /usr/local/Cellar/ruby/2.1.2/lib/ruby/gems/2.1.0
  ...
~ jweiss$ ls /usr/local/Cellar/ruby/2.1.2/lib/ruby/gems/2.1.0
bin		    bundler		doc		    gems
build_info	cache		extensions	specifications

インストールされているすべてのgemコードは、gemsの下にあります。 ディレクトリ。

これらのパスはシステムごとに異なり、Rubyのインストール方法によっても異なります(rvmはHomebrewとは異なり、rbenvとは異なります)。つまり、gem environment 宝石のコードがどこにあるかを知りたいときに役立ちます。

gemコードはどのように必要になりますか?

宝石内のコードを使用しやすくするために、RubyGemsはRubyのrequireをオーバーライドします 方法。 (これはcore_ext / kernel_require.rbで行われます)。コメントはかなり明確です:

core_ext / kernel_require.rb
  ##
  # When RubyGems is required, Kernel#require is replaced with our own which
  # is capable of loading gems on demand.
  #
  # When you call <tt>require 'x'</tt>, this is what happens:
  # * If the file can be loaded from the existing Ruby loadpath, it
  #   is.
  # * Otherwise, installed gems are searched for a file that matches.
  #   If it's found in gem 'y', that gem is activated (added to the
  #   loadpath).
  #

たとえば、active_supportをロードしたいとします。 。 RubyGemsはRubyのrequireを使用してそれを要求しようとします 方法。このエラーが発生します:

LoadError: cannot load such file -- active_support
	from (irb):17:in `require'
	from (irb):17
	from /usr/local/bin/irb:11:in `<main>'

RubyGemsはそのエラーメッセージを見て、active_support.rbを見つける必要があることを確認します。 代わりに、宝石の中に。そのために、gemのメタデータをスキャンして、active_support.rbを含むgemを探します。 :

irb(main):001:0> spec = Gem::Specification.find_by_path('active_support')
=> #<Gem::Specification:0x3fe366874324 activesupport-4.2.0.beta1>

次に、アクティブ化 gemは、gem内のコードをRubyのロードパス(requireできるディレクトリ)に追加します。 からのファイル:

irb(main):002:0> $LOAD_PATH
=> ["/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin14.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin14.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/2.1.0/x86_64-darwin14.0"]
irb(main):003:0> spec.activate
=> true
irb(main):004:0> $LOAD_PATH
=> ["/usr/local/Cellar/ruby/2.1.2/lib/ruby/gems/2.1.0/gems/i18n-0.7.0.beta1/lib", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/gems/2.1.0/gems/thread_safe-0.3.4/lib", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0.beta1/lib", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin14.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/site_ruby", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin14.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/vendor_ruby", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/2.1.0", "/usr/local/Cellar/ruby/2.1.2/lib/ruby/2.1.0/x86_64-darwin14.0"]

これで、active_support ロードパス上にある場合は、require 他のRubyコードと同じようにgem内のファイル。 requireの元のバージョンを使用することもできます 、RubyGemsによって上書きされたもの:

irb(main):005:0> gem_original_require 'active_support'
=> true

かっこいい!

少しの知識が大いに役立ちます

RubyGemsは複雑に見えるかもしれません。 しかし、最も基本的なレベルでは、Rubyのロードパスを管理しているだけです。 それがすべて簡単だと言っているわけではありません。 RubyGemsがgem、gemバイナリ(railsなど)間のバージョンの競合を管理する方法については説明しませんでした およびrake )、C拡張機能、その他たくさんのもの。

しかし、この表面レベルでもRubyGemsを知っていると、大いに役立ちます。 irbで少しコードを読んで再生する 、あなたはあなたの宝石の源に飛び込むことができるでしょう。宝石がどこにあるかを理解できるので、RubyGemsがそれらについて知っていることを確認できます。そして、gemがどのようにロードされるかがわかれば、見た目がおかしなロードの問題を掘り下げることができます。

RailsとBundlerがgemを処理する方法について詳しく知りたい場合は、次の記事を確認してください:Railsはgemをどのように処理しますか?


  1. データスクレイピングはどのように機能しますか?

    これを読んでいるので、データスクレイピングの利点と、その自動化された手法により、すべての手作業を自分で行うことなく大量のデータを収集できることを聞いた可能性があります。 しかし、データスクレイピングはどのように正確に機能しますか?そして、それは難しいですか、それとも誰かがデータをスクレイピングする方法を学ぶことができますか? 多分それはあなたが好奇心を持っているからです。または、ビジネス(またはサイドハッスル)にもデータスクレイピングを使用できるかどうかを確認したい場合があります。 いずれにせよ、この短い記事の終わりまでに、データスクレイピングとは何か、スクレイピングプロセスが実際にど

  2. C++で例外はどのように機能しますか

    C ++では、例外処理はランタイムエラーを処理するプロセスです。例外は、C++で実行時にスローされるイベントです。すべての例外は、std::exceptionクラスから派生します。処理可能なランタイムエラーです。例外を処理しない場合は、例外メッセージを出力してプログラムを終了します。 例外は、C ++標準では、プログラム内で使用できるクラスとして定義されています。親子クラス階層の配置を以下に示します- C++の一般的な例外クラスは-です。 Sr.No。 例外と説明 1 std ::exception これは、すべての標準C++例外の例外および親クラスです。