49

たとえば、次のスニペットでメソッド名を見つけましたが、その文字が特殊なキーワードなのか、メソッド名の一部なのbundler?かわかりません。?

# 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
4

5 に答える 5

85

Ruby のメソッド名には、大文字と小文字、数字、アンダースコア_、および句読点記号!, ?,が含まれる場合があります=

メソッド名は、数字と文字で始めることはできず!、最後にのみ表示できます。?=

非 ASCII 文字をメソッド名に使用できますが、これは非常に紛らわしい状況につながる可能性があるため、一般的な方法ではありません。

必須ではありませんが、メソッド名を小文字で始めることをお勧めします。大文字で始まる名前は Ruby では定数であるためです。メソッドに定数名を使用することは引き続き可能ですが、インターピーターは名前を定数として検索するため、括弧なしで呼び出すことはできません。

def Capital
    nil
end

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

メソッド名を定義する際に、非常に広く一貫して使用されている規則は次のとおりです。

  1. メソッド名は完全に小文字で、_名前に含まれる単語の区切りとしてアンダースコアが使用されます (例: Math::sqrt, Array#each_index, ...)。

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

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

  4. セッター=の最後の文字は等号です (例: Array#[]=, ...)。Ruby インターピーターは、setter メソッドを呼び出すためのシンタックス シュガーを提供します。

    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 +@, Ruby 1.9+)     ║       ║
║                           ║                                             ║       ║
║ **                        ║ Exponentiation                              ║     2 ║
║                           ║                                             ║       ║
║ -                         ║ Unary minus (define with method name -@)    ║     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 では演算子構文でメソッドを呼び出すことはできません (ただし、ドット構文では機能します)。

演算子の元のセマンティクスにできる限り従うことをお勧めします。演算子の元の意味を知っている人にとっては、演算子がユーザー定義クラスでどのように機能するかを直感的に理解できるはずです。

この言語は、配列やハッシュ値にアクセスするために通常使用される特別な非 operatorメソッドの構文糖衣も提供します。[]メソッドは、[]任意のアリティで定義できます。

順序付け、等価、比較、およびパターン マッチングを除く、テーブル内のすべての二項演算子について、Ruby は省略代入の省略形も提供します (たとえば、x += yに展開しx = x + yます)。それらをメソッドとして定義することはできませんが、ベースとなる演算子を定義して動作を変更できます。

これらの文字は、通常のメソッド名の中で使用することはできません (たとえばdo&print、またはstart-up有効なメソッド名ではありません)。

于 2012-05-10T21:44:33.813 に答える
7

define_method他の人が言うことは組み込み構文には当てはまりますが、 +のようなメソッドを使用する場合に使用できるものにバックエンドの制限はないようですsend:

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

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

この事実は役に立ちます: たとえば、Rails のActiveSupport::Testing::Declarative.testメソッドは、複雑な変換を行わないように使用します:

test 'Some Controller#Method' do

次の名前の別のテストと競合する可能性がある、より健全な名前にします。

test 'Some Controller_Method' do

これはTesting Guideに記載されています。

好奇心: Java でも同様のことが起こります。Java 言語よりもバイトコード メソッド名の方が選択肢が多いのです。JVM では、バイトコードの数字で始まる関数に名前を付けることができるのはなぜですか?

于 2014-11-09T20:42:27.363 に答える
3

メソッド名は!?またはで終わることができ=ます。アンダースコアも使用できます。それに加えて、独自のクラス用に定義できる演算子 ( +*>>など) のように見えるいくつかのメソッドがあります。[]

于 2012-05-10T21:43:30.867 に答える
2

1つ追加するには、オブジェクトに名前のないメソッドを実行するように指示することもでき、それは という名前のメソッドを呼び出そうとし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には 1 つあります。MethodProc

一部の言語()では関数呼び出しの演算子であり、これはここで起こっていることとかなり似ているようです。

これは、Rails の JBuilder などで使用されます。

https://github.com/rails/jbuilder

O'Reilly Ruby book の 196 ページに記載されています。

ProcRuby 1.9 では、オブジェクトを呼び出す追加の方法が提供されています。角括弧の代わりに、ピリオドを前に付けた括弧を使用できます。

z = f.(x,y)

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

于 2015-02-12T16:46:36.020 に答える
0

使用できる文字はa-Z,0-9、先頭以外、_、および?(ブール関数の場合) および!(破壊関数の場合) および=(セッターの場合) です。

于 2012-05-10T21:43:26.050 に答える