I'm trying to figure a way to do create a class with only the class's name in PHP.
E.g.:
$class = "MyClass";
if(class_exists($class))
$unit = new $class($param1, $param2);
else
$unit = new Unit($param1, $param2);
Is there a way to do this in PHP? If possible, I'd also like to know if this is possible in Java.
Cheers! thanks in advance.
I don't know about PHP (haven't used it in years), but in Java you can do:
MyClass obj = (MyClass) Class.forName("MyClass").newInstance( );
Yep, it should work fine in PHP. I would write that like this in order to avoid duplicating all the parameters to the constructor (if they are the same, of course):
$class = 'MyClass';
if (! class_exists($class)) {
$class = 'Unit';
}
$unit = new $class($param1, $param2);
you can use double $ signs in PHP to make a variable well.. variable.
i.e.
$$class($param1,$param2);
I have not come across such a capability in Java.
Note: you probably don't want to call your class "class" as it is a reserved word ;)
Related
So, I don't really know how to formulate this correctly but I'll do my best.
I am writing a game engine (not really for anything, I am trying a lot of ways to get certain things working to practice with ways of programming). And for this I want scripting. And I know how to add scripts from within Java but I have seen game engines that use multiple languages.
So what I want is to add python scripts that are run from with the Java process and can interact with Java object.
Like this Java Object that has some parameters (just an example)
public class Entity {
Script script = new Script ( "example.py" );
loc_x = 0;
loc_y = 0;
loc_z = 0;
public void update () {
script.run ();
}
}
With the python script being this
loc_x += 1
loc_z = loc_x
or
entity.loc_x += 1
entity.loc_z = entity.loc_x
I just have no way how to implement this. If this question has already been asked than please show me. If Runtime.getRuntime ().exec ( "example.py" ); is my best shot for this than that's fine. In that case I just want to know how to share those parameters.
Also, if another language (for example; LUA) is better for something like this then that's also fine. I am just completely blank on this subject.
So actually this is quite simple to do with Java having this built in from the box.
Java has this thing that is called 'ScriptEngineManager'. To use it you just do the following:
ScriptEngineManager sem = new ScriptEngineManager ();
ScriptEngine se = sem.getEngineByName ( "python" );
Now there are a few ways to runa script. Simple call the se.eval () method. You can give this either a String or a Reader and this way it will run the script.
Now to make it have some variables simply use the se.put method. You need to give this two parameters; a String and an Object.
For example:
se.put ( "entity", entity ); // with entity being defined earlier
The onlt thing to keep in mind is that this script manager does not have built in python support. You need to either create your own ScriptEngine for this or use third party software. I found jython and this seems to be working prety well. If you download the standalone jar and put that in your classpath it works. No need for any function calling.
Now in the Script you can call any public member of entity. All the objects, values and those sub-objects get passed through to the script.
My end-code:
Entity class
public class Entity {
String source =
"entity.loc_x += 1\n" +
"entity.loc_z = entity.loc_x";
ScriptEngine se;
loc_x = 0;
loc_y = 0;
loc_z = 0;
public Entity () {
ScriptEngineManager sem = new ScriptEngineManager ();
se = sem.getEngineByName ( "python" );
se.put ( "entity", this );
}
public void update () {
se.eval ( source );
}
}
I hope I helped anyone with this. It was pretty fun tinkering with all of this.
I wrote a class which knows how to calculate the vector product and I want to call it in my main class. But when trying to use the class i get several Errors, that I can't explain or solve (see screenshot).
Problem_screenshot
try is keyword, you should not use it to name the variable/object.
xProduct productObj = new xProduct();
You just can not do this:
xProduct try = new xProduct();
because try is a reserved keyword in java
I just started learning about groovy and trying to transpose my java code to groovy scripts. Usually java allows you have a class with only methods that you can call from other classes. I wanted to translate that to groovy. I have in one file - lets call it File1- a method like this:
def retrieveData(String name){
// do something
}
and in the second file, File2, I call File1 like this:
def file1Class = this.class.classLoader.parseClass(new File("../File1.groovy"))
and then try to call the method in File1 like this:
def data = file1Class.retrieveData("String")
but it keeps giving me this error - MissingMethodException:
groovy.lang.MissingMethodException: No signature of method: static File1.retrieveData() is applicable for argument types: (java.lang.String) values: [String] Possible solutions: retrieveData(java.lang.String)
so it does recognize that I am sending in the correct number of parameters and even the correct object, but it isn't running the method as it should?
Is there something I am missing? I tried to remove the object definition from the method - in other words - like this:
def retrieveData(name){
// do something
}
but that didn't work either. I am clueless about what the next step would be. Can anyone please help push me in the right direction? I would greatly appreciate it.
See the answer provided in this StackOverflow reponse.
Use the GroovyScriptEngine class. What does the GroovyScriptEngine do? From the docs:
Specific script engine able to reload modified scripts as well as
dealing properly with dependent scripts.
See the example below.
def script = new GroovyScriptEngine( '.' ).with {
loadScriptByName( '..\File1.groovy' )
}
this.metaClass.mixin script
retrieveData()
Note how we use the loadScriptByNamemethod to
Get the class of the scriptName in question, so that you can
instantiate Groovy objects with caching and reloading.
This will allow you to access Groovy objects from files however you please.
I'm relying on an old Java API that kinda sucks and loves to throw null pointer exceptions when data is missing. I want to create a subclass that has option type accessors but preserves the old accessors until I decide I need to create safe accessors for them. Is there a good way to create a subclass from a copy of the original object? I'd like to achieve something like the following:
SafeIssue extends Issue {
def safeMethod: Option[Value] = { //... }
}
val issue = oldapi.getIssue()
val safeIssue = SafeIssue(issue)
//Preserves issue's methods and data if I need them
val unsafeVal = safeIssue.unsafeMethod
val maybeVal = safeIssue.safeMethod
Why not try an implicit conversion instead? This works better with Java APIs that like to create their own objects. So you would
class SafeIssue(issue: Issue) {
def original = issue
def safeFoo = Option(issue.foo)
// ... You must write any of these you need
}
implicit def make_issues_safe(issue: Issue) = new SafeIssue(issue)
Then you can--as long as you've supplied the method--write things like
val yay = Issue.myStaticFactoryMethodThing.safeFoo.map(x => pleaseNoNull(x))
(You can then decide whether you want to carry SafeIssue or Issue around in your code, and you can always get back the Issue from SafeIssue with the exposed original method (or you could make the issue parameter a val.)
Is there a way to create ruby value objects or hashes from java objects in jruby application ? Thank you.
I am not sure whether this is what you are trying to achieve, but to convert a Java object into a ruby hash, you could do something like this:
require 'java'
java_import 'YourJavaClass'
a = YourJavaClass.new
hash = {}
a.java_class.fields.each{ |var| hash[var.name] = var.value(a) }
p hash
This assumes that the instance variables are accessible (public). If they are not, you may need to make them accessible with something like:
a.java_class.declared_fields.each{ |var| var.accessible = true; hash[var.name] = var.value(a) }
(Note that this time it uses declared_fields)
Names and Beans Convention gives us next opportunity for properties with accessors
def java_to_hash(java_obj)
hash = {}
java_obj.methods.grep(/get_/).each do |accessor|
if accessor.eql? "get_class" then
next
end
#get_user_name => user_name
method_name = accessor[4..-1]
if java_obj.respond_to?(method_name)
hash[method_name.to_sym] = java_obj.send(accessor.to_sym)
end
end
hash
end