2012-05-10 13 views
40

たとえば、次のスニペットでメソッド名bundler?が見つかりました。?文字が特殊キーワードか、メソッド名の一部かどうかはわかりません。 (セッターのための)(ブール機能のため)、先頭に限りないよう0-9a-Z,_、および?!(破壊的な機能のための)と=Rubyのメソッド名にはどのような制限がありますか?

# This is a predicate useful for the doc:guides task of applications. 
def bundler? 
    # Note that rake sets the cwd to the one that contains the Rakefile 
    # being executed. 
    File.exists?('Gemfile') 
end 

答えて

72

メソッド名は、大文字と小文字、数字を含んでいてもよい、_を強調し、赤点斑は!?=に署名します。

メソッド名は数字で始めることはできません。!,?および=の文字は末尾にのみ表示できます。

メソッド名に非ASCII文字を使用できますが、これは非常に混乱する可能性があり、一般的ではありません。

大文字で始まる名前はRubyの定数であるため、メソッド名を小文字で開始するのは必須ではありませんが、これは必須です。これは、メソッドの定数名を使用することは可能ですが、interpeterは定数としての名前のためのアップになりますので、あなたは、括弧なしでそれを呼び出すことができなくなります。

def Capital 
    nil 
end 

Capital # NameError: uninitialized constant Capital 
Capital() # => nil 

いくつかの非常に広範囲に及びメソッド名を定義するときに、一貫規則を使用しています。

  1. メソッド名の名前に単語の区切り(例えばMath::sqrtArray#each_index、...)として_アンダースコアで、フルダウンケースです。

  2. 述語は、最後の文字(例えばArray#empty?Hash#has_key?、...)として疑問符?を持っています。述語は通常ブール値を返しますが、これは必ずしもそうではありません。これらのメソッドは、述語が偽と評価された場合はnilまたはfalseを返すだけです(そうでない場合はFile::size?を返します)。ファイルが存在しない場合はnil、それ以外の場合はInteger)。

  3. 呼び出されるオブジェクトの状態を変更するか、異常な動作をするメソッドは、最後の文字として感嘆符!を持ちます。このメソッドは、通常と呼ばれ、他のメソッド(たとえばArray#sort!Array#slice!、...)の破壊的またはインプレースバージョンであるため、と呼ばれます。

  4. セッターは、最後の文字(例えばArray#[]=、...)として等号=を有します。 Rubyのinterpeterは、setterメソッドのinvokationため糖衣構文を提供しています:

    a = [4, 5, 6] 
    a[0] = 3 # Shorthand for a.[]=(0, 3) 
    

Rubyは、メソッド名として演算子記号を使用して演算子を定義することができます:

╔═══════════════════════════╦═════════════════════════════════════════════╦═══════╗ 
║ Operators (by precedence) ║     Operations     ║ Arity ║ 
╠═══════════════════════════╬═════════════════════════════════════════════╬═══════╣ 
║ ! ~ +      ║ Boolean NOT, bitwise complement, unary plus ║  1 ║ 
║       ║ (define with method name [email protected], Ruby 1.9+)  ║  ║ 
║       ║            ║  ║ 
║ **      ║ Exponentiation        ║  2 ║ 
║       ║            ║  ║ 
║ -       ║ Unary minus (define with method name [email protected]) ║  1 ║ 
║       ║            ║  ║ 
║ */%      ║ Multiplication, division, modulo   ║  2 ║ 
║       ║            ║  ║ 
║ + -      ║ Addition, subtraction      ║  2 ║ 
║       ║            ║  ║ 
║ << >>      ║ Bitwise shift        ║  2 ║ 
║       ║            ║  ║ 
║ &       ║ Bitwise AND         ║  2 ║ 
║       ║            ║  ║ 
║ |^      ║ Bitwise OR, Bitwise XOR      ║  2 ║ 
║       ║            ║  ║ 
║ < <= => >     ║ Ordering         ║  2 ║ 
║       ║            ║  ║ 
║ == === != =~ !~ <=>  ║ Equality, pattern matching, comparison  ║  2 ║ 
╚═══════════════════════════╩═════════════════════════════════════════════╩═══════╝ 

単項演算子メソッドがあります引数を渡さなかった。バイナリ演算子メソッドは引数を渡され、それを操作してselfに作用します。

厳密には演算子のアライメントを守ることが重要です。異なるアリティ(例えば2つの引数をとる+メソッド)を持つ演算子メソッドを定義することは可能ですが、Rubyでは演算子構文でメソッドを呼び出すことはできません(ただし、ドット構文では機能します)。

オペレータの元の意味をできるだけ忠実に守っておくことをお勧めします。オペレータの元の意味を知っているユーザにとっては、ユーザ定義のクラスでどのように動作するかを直感的に理解する必要があります。

言語は、通常、配列とハッシュ値にアクセスするために使用される特別な演算子以外の[]メソッドの構文砂糖を提供します。 []メソッドは任意のアリティで定義できます。

順序、等価、比較、パターンマッチングを除いて、テーブル内のすべてのバイナリ演算子について、Rubyでは短縮割り当ての略語も提供します(x += yx = x + yに展開されます)。それらをメソッドとして定義することはできませんが、それらの基になっている演算子を定義する動作を変更することができます。

通常のメソッド名内では使用できません(do&printまたはstart-upは有効なメソッド名ではありません)。他の人が組み込みの構文については、真実であると言う何

+1

ちょっと注意してください:偽( 'nil'や' false')やtruethy(その他すべて)の値を返すのは、 'true'と' false'ではなく、述語のメソッド( '? '戻り値は 'true'と' false'のように動作する 'if'文で使用されることを意図していますが、実際の戻り値は意図したメソッドインタフェースの一部ではない場合があります。 –

+0

アドバイスをいただき、ありがとうございました。 –

+0

メソッド名全体としてしか使用できないいくつかの文字もあります。つまり、+ + ** ** /(これらの演算子をオーバーロードしている場合)foo + barというメソッドは定義できません。 –

2

メソッド名は、!,?または=で終わることがあります。下線も許されます。また、独自のクラスに定義できる演算子(例:+*>>[])のようないくつかのメソッドがあります。 Rubyで

4

は、しかし、あなたがdefine_method + sendのようなメソッドを使用する場合に使用することができるものには、バックエンドの制限はないと思わ:

define_method(:'$% ^&') { 0 } 
define_method(:'你好') { 1 } 

send(:'$% ^&') == 0 or raise 
send(:'你好') == 1 or raise 

この事実は、することができます便利:

:別のテストという名前と競合する可能性があります正気名に

test 'Some Controller#Method' do 

:上の複雑な変換をしないように、例えばRailsのActiveSupport::Testing::Declarative.test方法は、それを使用しています

test 'Some Controller_Method' do 

これはTesting Guideで言及されています。

好奇心:一つのことを追加するにはWhy does the JVM allow us to name a function starting with a digit in bytecode?

2

:同様のことは、バイトコードのメソッド名は、Java言語以外の方法より多くの選択肢を提供するJava、で起こるあなたもなしでメソッドを実行するためのオブジェクトを伝えることができますすべてに名前を付け、それがcallという名前のメソッドを呼び出すようにしようとします:

#!/usr/bin/env ruby 

class Foo 

=begin 
    def call(*args) 
    puts "received call with #{args.join(' ')}" 
    end 
=end 

    def method_missing(m, *args, &block) 
    puts "received method_missing on `#{m}(#{args.join(', ')})`" 
    end 

end 

f = Foo.new 
f.('hi')    # Not a syntax error! method_missing with m of :call 
f.send :'', 'hmm' # method_missing with m set to :'' 
f.send nil, 'bye' # raises an error 

という名前call定義さObject上の任意の方法は実際にありませんが、Methodとに1がありますクラス。

いくつかの言語では、()は、関数呼び出しの演算子であり、ここで起こっていることにかなり似ています。

RailsのJBuilderで:

https://github.com/rails/jbuilder

それはオライリーRubyの本の196ページに記載されています:

のRuby 1.9はProcオブジェクトを呼び出すための追加的な方法を提供しています。ブラケットを広場に代わるものとして、あなたはピリオドで始まる括弧を使用することができます

z = f.(x,y) 

.()をメソッド名を欠落しているメソッド呼び出しのように見えます。これは、定義できる演算子ではなく、callメソッドを呼び出す構文糖です。これは、callメソッドを定義する任意のオブジェクトで使用でき、Procオブジェクトに限定されません。