2011-10-05 11 views
1

Rubyで 'main'メソッド内でクラスメソッドを呼び出すことができるかどうかは疑問です。メソッドがRubyの 'main'メソッド内で呼び出されたときの未定義メソッドエラー?

以下のコードではエラーが発生します。

test.rb

class Client 
    def printtwo 
     puts 2 
    end 

    if __FILE__ == $0  #if this file gets run by an interpreter, run below codes 
          #just like main() method in java 

     printtwo()   #this throws below error 
          #undefined method `printtwo' for Client:Class (NoMethodError) 
    end 
end 

クラス宣言のないコードが正常に動作しながら、私は

test2.rb

def printtwo 
    puts 2 
end 

if __FILE__ == $ 
    printtwo()   #this prints 2 
end 

それらを実行する場合、私はクラス宣言内でこの実行可能ファイルを使用したい理由があるためであります私はattr_accessorを設定してクラス変数を使いたいと思っています。私はこのattr_accessorをクラスで使用しなければならないと信じています。右?

メソッドコールでエラーが発生しないようにこの問題を解決するにはどうすればよいですか?

答えて

4

最初の例のようにそのメソッドを定義すると、それはクラスメソッドではなくインスタンスメソッドであるため、呼び出すことができないのは、呼び出すインスタンスがないためです。しかし、あなたはそれクラスメソッドにする場合、メソッド名にself.を付加することで、それがうまくいく:

class Client 
    def self.printtwo 
     puts 2 
    end 

    printtwo 
end 

しかし、私はあなたがやっていることについて、もう少し考えたいかもしれない印象を受けます。クラス宣言の中でそのようなコードを実行することはめったにありません(例えば、関数やインスタンス変数をプログラム的に定義している場合を除きます)。あなたはもう少しattr_accessorになっているはずです - このようなものは通常、あなたが必要とするすべてである:

class Client 
    attr_accessor :ivar_one 
    attr_accessor :ivar_two 
end 

は、この情報がお役に立てば幸い!

+0

したがって、 'def self.method_name'はJavaのプライベートメソッドと似ていますが、それはクラスの内部でしか呼び出せないからです。 – user482594

+0

@ user482594 - これは実際には(多かれ少なかれ) 'static'と同等です。 'instance_of_myclass.method'ではなく' MyClass.method'を呼び出すことを意味します。アクセシビリティには影響しません。 –

0

これは驚くことではありません。

selfを使用して)メソッドを静的にすると、正常に動作するようにすることができます。これは、クラスのインスタンスが存在しない場合に呼び出すことはできません。

class Client 
    def self.printtwo 
     puts 2 
    end 

    if __FILE__ == $0  #if this file gets run by an interpreter, run below codes 
          #just like main() method in java 

     printtwo()   #this throws below error 
          #undefined method `printtwo' for Client:Class (NoMethodError) 
    end 
end 

はまた、あなたは、任意のインスタンスを持っていないので、あなたは、静的クラスにインスタンスの属性(@var)にアクセスすることができないことに注意してください。クラス属性(@@ var)のみが可能です。

これは、いつでもあなたのオブジェクトに新しいattr_accessorを設定できると言っています。 Rubyはコードを書くコードを持つことができます...メタプログラミングのための素晴らしい言語。

Here is a question explaining how to do create a attr_accessor through a method.

2

printtwoがインスタンスメソッドであるためです。これは、Clientクラス内の他のインスタンスメソッドから呼び出すことができますが、他のメソッドの外でメソッドを呼び出すので、動作しません。

ファイルを読み込むと、クラスが読み込まれるため、クライアントクラスがインスタンス化される前にprinttwoメソッドが呼び出されます。例では、私はクラス内で呼び出されると、外呼び出されたメソッド作ら

def self.printtwo 
    # code 
end 

http://repl.it/Bax/1

注意:あなたがそうであるようにprinttwoを呼び出すには、としてそれを定義する必要があります。

class Client 
    def printtwo 
    puts 2 
    end 
end 

if __FILE__ == $0 
    Client.new.printtwo 
end 

それは:他の回答に加えて

0

、私はif __FILE__ == $0内の任意のコードが一般的に上記のすべての定義仕事をした後、あなたのプログラムを開始、終了時にわずか数行になることを追加したいですすべてのクラス定義の中にif __FILE__ == $0という条件が表示された場合、あまりにも扱いにくいものになります。このコードは、ファイルを明示的に実行する場合にのみ定義されていますが、柔軟性のために、書いたコードをプログラムの他の部分や他のプログラムに(includeを介して)利用できるようにしてください。代わりに、ファイルのメインコンテキスト内の1つの場所に小さくしてください。

また、メタプログラミングのときでも、メソッド定義やインスタンス/クラス変数宣言以外のクラスコンテキスト内でコードを実行することは珍しいことではなく、必ずしも問題はありません。 Rubyで大いに盛り上がる傾向があります。

関連する問題