Method invocation in class definition?
In Ruby, class declarations are just chunks of code, executed in order.
It's important to remember that inside a class definition, self
points to the class itself. validates
is a class method of ActiveRecord
. As the class is being defined, code in the definition is executed. The validates
method resolves to a class method of ActiveRecord
, so is called during class definition.
In your Person
example, it will only print once, because you only define the class once.
Consider the following:
class Foo
def self.validates_nothing(sym)
(@@syms ||= []) << sym
puts "!!! Here there be logic"
end
def validate
@@syms.each { |s| puts s }
end
end
This defines a class with a class method validates_nothing
, and an instance method, validate
. validates_nothing
just gathers whatever arguments are given it, validate
just dumps them out.
class Bar < Foo
validates_nothing :anything
validates_nothing :at_all
end
This defines a subclass. Note that when the class method validates_nothing
is called, it prints:
Here there be logic
Here there be logic
If we create a new bar and call validate, we get the expected output:
> Bar.new.validate
!!!anything
!!!at_all
Python calling method in class
The first argument of all methods is usually called self
. It refers to the instance for which the method is being called.
Let's say you have:
class A(object):
def foo(self):
print 'Foo'
def bar(self, an_argument):
print 'Bar', an_argument
Then, doing:
a = A()
a.foo() #prints 'Foo'
a.bar('Arg!') #prints 'Bar Arg!'
There's nothing special about this being called self
, you could do the following:
class B(object):
def foo(self):
print 'Foo'
def bar(this_object):
this_object.foo()
Then, doing:
b = B()
b.bar() # prints 'Foo'
In your specific case:
dangerous_device = MissileDevice(some_battery)
dangerous_device.move(dangerous_device.RIGHT)
(As suggested in comments MissileDevice.RIGHT
could be more appropriate here!)
You could declare all your constants at module level though, so you could do:
dangerous_device.move(RIGHT)
This, however, is going to depend on how you want your code to be organized!
method that gets a class and calls its main function
Given below is how you should define the method:
public static void executeMain(Class<?> cls, Object[] args) {
try {
Object[] param = { args };
Method method = cls.getDeclaredMethod("main", args.getClass());
method.invoke(cls, param);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
}
Demo
Assignment1.java:
import java.util.Arrays;
public class Assignment1 {
public static void main(String[] args) {
if (args == null) {
System.out.println("Welcome to Assignment1");
} else {
System.out.println("Arguments to main in Assignment1: " + Arrays.toString(args));
}
}
}
Assignment2.java
import java.util.Arrays;
public class Assignment2 {
public static void main(String[] args) {
if (args == null) {
System.out.println("Welcome to Assignment2");
} else {
System.out.println("Arguments to main in Assignment2: " + Arrays.toString(args));
}
}
}
Test class:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) {
Assignment1.main(null);
Assignment1.main(new String[] { "Hello", "World" });
Assignment2.main(null);
Assignment2.main(new String[] { "Hello", "World" });
executeMain(Assignment1.class, new String[] { "Good", "Morning" });
executeMain(Assignment2.class, new String[] { "Good", "Morning" });
}
public static void executeMain(Class<?> cls, Object[] args) {
try {
Object[] param = { args };
Method method = cls.getDeclaredMethod("main", args.getClass());
method.invoke(cls, param);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
}
}
Output:
Welcome to Assignment1
Arguments to main in Assignment1: [Hello, World]
Welcome to Assignment2
Arguments to main in Assignment2: [Hello, World]
Arguments to main in Assignment1: [Good, Morning]
Arguments to main in Assignment2: [Good, Morning]
Check this to learn more about Java Reflection API.
Method invocation vs method execution
Invoking a method and executing a method are synonyms - they are they same thing.
Perhaps I am misunderstanding your question.
Java language spec: an invocation of Class as return type of method in annotation type
Yes, that's exactly that. The terminology is confusing, rarely used, and I can't seem to find it anywhere in the JSL. It is in a tutorial, though:
To reference the generic
Box
class from within your code, you must
perform a generic type invocation, which replacesT
with some concrete
value, such as Integer:Box<Integer> integerBox;
You can think of a generic type invocation as being similar to an
ordinary method invocation, but instead of passing an argument to a
method, you are passing a type argument —Integer
in this case — to
theBox
class itself.Type Parameter and Type Argument Terminology:
Many developers use the terms "type parameter" and "type argument"
interchangeably, but these terms are not the same. When coding, one
provides type arguments in order to create a parameterized type.
Therefore, theT
inFoo<T>
is a type parameter and the String in
Foo<String> f
is a type argument. This lesson observes this definition
when using these terms.Like any other variable declaration, this code does not actually
create a newBox
object. It simply declares thatintegerBox
will hold
a reference to a "Box
ofInteger
", which is howBox<Integer>
is read.An invocation of a generic type is generally known as a parameterized
type.
The best way to invoke methods in Python class declarations?
Quite simply, the solution is that f does not need to be a member of the class. I am assuming that your thought-process has gone through a Javaish language filter causing the mental block. It goes a little something like this:
def f(n):
return '<' + str(num) + '>'
class C(object):
v = f(9)
w = f(42)
Then when you want to use f again, just use it
>>> f(4)
'<4>'
I think the moral of the tale is "In Python, you don't have to force everything into a class".
Invoking a method of an anonymous class
Can somebody point me to the part of the specification that addresses this?
This will mostly be defined in the section concerning Method invocation expressions:
The first step in processing a method invocation at compile time is to
figure out the name of the method to be invoked and which class or
interface to search for definitions of methods of that name.For the class or interface to search, there are six cases to consider,
depending on the form that precedes the left parenthesis of the
MethodInvocation:
- [...]
- If the form is
Primary . [TypeArguments] Identifier
, then letT
be
the type of the Primary expression. The class or interface to search
isT
ifT
is a class or interface type, or the upper bound ofT
ifT
is a type variable.
Here, the Primary expression is the class instance creation expression. So the type to search is the anonymous type.
Am I right in thinking that the only way you can invoke hello is
immediately like this. What about reflection?
As long as an expression evaluates to the anonymous type T
, whether through direct access like you have, or through generics, you have access (regular access rules apply) to the members that T
declares. This isn't limited to methods. You can access fields or types, though it's not as useful for types. For example,
Object var = new Object() {
class Nested {
}
}.new Nested();
Since there's no way to refer to the nested type without the enclosing type, you can't declare a variable of that nested type. The usefulness declines very quickly. (Presumably, that's also why you can't have a static
nested type within this anonymous class.)
Reflection also exposes this method. The generated anonymous class contains this method, so you can retrieve it and invoke it. The process is the same. The fact that the instance is from an anonymous class doesn't matter. The same strategy as presented in How do I invoke a Java method when given the method name as a string? applies.
For example,
Object ref = new Object() {
public void method() {
System.out.println("hidden");
}
};
Class<?> anonymousClass = ref.getClass();
Method method = anonymousClass.getMethod("method");
method.invoke(ref, new Object[0]);
Don't ever write code like this.
Call Class Method From Another Class
update: Just saw the reference to call_user_func_array
in your post. that's different. use getattr
to get the function object and then call it with your arguments
class A(object):
def method1(self, a, b, c):
# foo
method = A.method1
method
is now an actual function object. that you can call directly (functions are first class objects in python just like in PHP > 5.3) . But the considerations from below still apply. That is, the above example will blow up unless you decorate A.method1
with one of the two decorators discussed below, pass it an instance of A
as the first argument or access the method on an instance of A
.
a = A()
method = a.method1
method(1, 2)
You have three options for doing this
- Use an instance of
A
to callmethod1
(using two possible forms) - apply the
classmethod
decorator tomethod1
: you will no longer be able to referenceself
inmethod1
but you will get passed acls
instance in it's place which isA
in this case. - apply the
staticmethod
decorator tomethod1
: you will no longer be able to referenceself
, orcls
instaticmethod1
but you can hardcode references toA
into it, though obviously, these references will be inherited by all subclasses ofA
unless they specifically overridemethod1
and do not callsuper
.
Some examples:
class Test1(object): # always inherit from object in 2.x. it's called new-style classes. look it up
def method1(self, a, b):
return a + b
@staticmethod
def method2(a, b):
return a + b
@classmethod
def method3(cls, a, b):
return cls.method2(a, b)
t = Test1() # same as doing it in another class
Test1.method1(t, 1, 2) #form one of calling a method on an instance
t.method1(1, 2) # form two (the common one) essentially reduces to form one
Test1.method2(1, 2) #the static method can be called with just arguments
t.method2(1, 2) # on an instance or the class
Test1.method3(1, 2) # ditto for the class method. It will have access to the class
t.method3(1, 2) # that it's called on (the subclass if called on a subclass)
# but will not have access to the instance it's called on
# (if it is called on an instance)
Note that in the same way that the name of the self
variable is entirely up to you, so is the name of the cls
variable but those are the customary values.
Now that you know how to do it, I would seriously think about if you want to do it. Often times, methods that are meant to be called unbound (without an instance) are better left as module level functions in python.
Related Topics
Storing Passwords for External APIs - Best Practice
Remove Subdomain from String in Ruby
How to Split a String by Commas Except Inside Parenthesis, Using a Regular Expression
How to Model a Mutual Friendship in Rails
Select Checkbox Pass Array in Ruby on Rails
How Do Version Numbers Work for Mri Ruby
How to Count Existing Instances of a Class in Ruby
Unpermitted Parameters for Dynamic Forms in Rails 4
Simplest Way to Send Raw Byte-Arrays Using Ruby's Tcpsocket-Class
Stop Loading Page Watir-Webdriver
Ruby.Metaprogramming. Class_Eval
Is There Some Kind of Unseen Array Termination in Ruby
Interested in What the "<<" Does