Reputation: 17486
I am wondering if it is possible to call class methods within 'main' method in Ruby.
Below codes produces an error.
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
While codes without class declaration runs fine if I run them
test2.rb
def printtwo
puts 2
end
if __FILE__ == $
printtwo() #this prints 2
end
The reason that I want to use this executable inside a class declaration is because, I want to use class variables by setting attr_accessor
. I believe this attr_accessor
has to be used in a class. right?
How can I resolve this problem so that method call will not produce an error?
Upvotes: 1
Views: 2558
Reputation: 8434
Ok so it's not surprising. You can't call a method if there is no instance of the class (which is the case in your example)
You can try to make the method static (by using self
) it should work.
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
Also note that you cannot access instance attributes (@var) into a static class because you don't have any instance. You can only class attributes (@@var).
This said, you can set new attr_accessor
in your object at any time. Ruby allows you to have code writing code... Pretty awesome language for meta programming.
Here is a question explaining how to do create a attr_accessor through a method.
Upvotes: 0
Reputation: 6066
In addition to the other answers, I'd add that any code inside if __FILE__ == $0
would typically be only a few lines at the end, starting your program after doing all the definition work above:
class Client
def printtwo
puts 2
end
end
if __FILE__ == $0
Client.new.printtwo
end
It would get too unmanageable if you had the if __FILE__ == $0
condition appearing inside every class definition. That code only works by definition if you run the file explicitly, but for flexibility you'd generally want any code you've written to be available (via include
) to other parts of the program and to other programs. Instead just keep it small and in one place in the main context of your file.
Also, it's uncommon to run any code inside a class context other than method definition and instance/class variable declaration, even when you're meta-programming, not that there's necessarily an issue with this, it just doesn't tend to crop up much in Ruby.
Upvotes: 0
Reputation: 17179
This is because printtwo
is an instance method. It can be called from other instance methods within the Client
class but since you are calling the method outside of any other methods, it won't work.
When you load the file, the class is read and hence the printtwo
method is called before the Client class is instantiated. In order to call printtwo
as you do, you will have to define it as:
def self.printtwo
# code
end
Notice in the example I made which method gets called within the class and which gets called outside.
Upvotes: 2
Reputation: 14619
If you define that method like you do in your first example, it's an instance method rather than a class method, and that's why you can't call it - because you don't have an instance to call it on. But if you make it a class method, by prepending self.
to the method name, it'll work:
class Client
def self.printtwo
puts 2
end
printtwo
end
But I get the impression you might want to think a little more about what you're doing. You rarely need to run code like that inside a class declaration (unless, say, you're programatically defining a bunch of functions or instance variables). You should look into attr_accessor
a little more - something like this is usually all you need:
class Client
attr_accessor :ivar_one
attr_accessor :ivar_two
end
Hope this helps!
Upvotes: 4