web-dev-qa-db-ja.com

Rubyのメソッド名の制限は何ですか?

たとえば、次のスニペットでメソッド名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
45
stanigator

Ruby=のメソッド名には、大文字と小文字、数字、アンダースコア___、および句読点記号_!_、_?_、_=_。

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

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

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

_def Capital
    nil
end

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

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

  1. メソッド名は完全な小文字で、名前への単語の区切り文字としてアンダースコア___を使用します(例:_Math::sqrt_、_Array#each_index_、...)。

  2. 述語最後の文字として疑問符_?_を使用します(例:_Array#empty?_、_Hash#has_key?_、...)。述語は通常ブール値を返しますが、常にそうであるとは限りません。これらのメソッドは、述語がfalseと評価された場合はnilまたはfalseを返し、それ以外の場合は値を返します(例:_File::size?_は、ファイルが存在しない場合はnilを返し、ファイルのサイズはIntegerとして返します)。

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

  4. セッター最後の文字として等号_=_を使用(例:_Array#[]=_、...); Ruby interpeterは、セッターメソッドの呼び出し用に構文糖を提供しています:

    _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では演算子構文でメソッドを呼び出すことができません(それはただし、ドット構文で機能します)。

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

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

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

これらの文字は通常のメソッド名内では使用できません(例:_do&print_または_start-up_は有効なメソッド名ではありません)。

78

他の人が言うことは組み込み構文に当てはまりますが、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

次の名前の別のテストと競合する可能性があるsaner名に変更します。

test 'Some Controller_Method' do

これは テストガイド で言及されています。

好奇心:Javaでも同様のことが起こり、バイトコードメソッド名がJava言語: JVMで数字で始まる関数に名前を付けることができる理由)バイトコードで?

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

2
Michael Kohl

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という名前のメソッドは実際にはありませんが、MethodおよびProcクラスで定義されています。

一部の言語では、_()_は関数呼び出しの演算子であり、これはここで行われていることと非常によく似ています。

これは、たとえば使用されます。 RailsのJBuilderで:

https://github.com/Rails/jbuilder

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

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

_z = f.(x,y)
_

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

2

使用できる文字は次のとおりです:a-Z,0-9最初にない限り、_?(ブール関数の場合)および!(破壊的機能用)および=(セッター用)。

0
Linuxios