2016-09-01 4 views
4

純粋なRuby irbでは{if: 1}を入力できません。 irbはifがシンボルではなくif文の先頭であると考えているため、この文は終了しません。Railsでハッシュキーとして `if`を使うことはできますが、Rubyでは使用できないのはなぜですか?

なぜ、パラメータとしてifを受け入れるbefore_filterを持つことができますか?

class Order < ApplicationRecord 
    before_save :normalize_card_number, if: :paid_with_card? 
end 

同じことが同様にunlessに起こる:ガイドでは、のようなコードを持っています。

+1

このバグが数か月前に報告されたことを知りました:[Bug#12177:* irbコンソールの新しいハッシュ構文を持つハッシュのシンボルとして 'if:'を使用する*](https://bugs.ruby -lang.org/issues/12177) –

答えて

3

IRbのパーサーはよく分かっています。 (実際に遭遇したバグは、数ヶ月前にすでに報告されていました:Bug #12177: Using if: as symbol in hash with new hash syntax in irb console is not working。)無視してください。 IRbとRubyとの間には、文法だけでなく、意味論的な違いもあります。例えば。最上位レベルで定義されたメソッドは、暗黙的にprivateの代わりに暗黙的にpublicです。

IRbは、独自のパーサーを使用してコードを解析して解析します。 ENTERを押すか、次の行でコードを続行するのを待ってエンジンに送信するかどうかを指定します。しかし、Rubyの構文は非常に複雑であるため、正しく解析するのは非常に難しく、IRbのパーサはRubyの構文解析から逸脱することが知られています。

他のREPLは異なるアプローチをとります。 Pryは実際にRubyパーサを独自のパーサではなく使用しています。

+0

「壊れていることはよく知られている」という言及がありますか?私は、それに関する適切な議論があるかどうかを知りたがっているのか不思議です。 – lulalala

7

これはRubyではなくirbの問題です。

bash=> ruby -e "puts({if: 1})" 
bash=# {:if=>1} 

代わりにpryを使用できます。入力を正しく読み込みます。

https://github.com/pry/pry

0

あなたの例のコードは、RailsのDSLの一部です。あなたが実際に設定しているのはちょうどコードのように見えるハッシュです。

内部的に、Railsはbefore_saveコールの条件を指定するこのハッシュを評価します。非常に単純化されたバージョンで

、保存時にRailsは基本的にこれを行います:

再び
class ActiveRecord::Base 
    @before_save_rules = [] 
    def self.before_save(method, options={}) 
    @before_save_rules << [method, options] 
    end 

    def self.before_save_rules 
    @before_save_rules 
    end 

    def save 
    # Evaluate the defined rules and decide if we should perform the 
    # before_save action or not 

    self.class.before_safe_rules.each do |method, options| 
     do_perform = true 
     if options.key?(:if) 
     do_perform = false unless send(options[:if]) 
     end 

     if options.key?(:unless) 
     do_perform = false if send(options[:unless]) 
     end 

     send(method) if do_perform 
    end 

    # now perform the actual save to the database 
    # ... 
    end 
end 

、これは非常に単純化され、ちょうど実際のコードの精神であるが、これはそれがどのように動作するか基本的にあります。

関連する問題