Scala - unbound wildcard exception (Play Framework 2.3 Template) - scala

I am using Play Framework 2.3 I am using the scala template engine to create my views and Java elsewhere.
My model extends an abstract parameterised object like so... (pseudo code)
Abstract object:
public abstract class MyObject<T> {
// various bits
public class MyInnerObject {
// more stuff
}
}
Model object (singleton)
public class SomeModel extends MyObject<SomeBean> {
public static SomeModel getInstance() {
if (instance == null)
instance = new SomeModel();
return instance;
}
// more bits
}
I then pass the model to the view from another view helper:
#MyHelper(SomeModel.getInstance())
MyHelper scala view template:
#*******************************************
* My helper
*******************************************#
#(myObj: some.namespace.MyObject[_])
#import some.namespace.MyObject
#doSomething(myInnerObj: MyObject[_]#MyInnerObject) = {
#* do some stuff *#
}
#for(myInnerObj <- myObj.getInnerObjects()) {
#doSomething(myInnerObj)
}
However I get an error on the line #doSomething(myInnerObj: MyObject[_]#MyInnerObject) stating
unbound wildcard exception
I am not sure the correct Scala syntax to avoid this error I had naively assumed that I could use the _ to specify arbitrary tyope but it won't let me do this.
What is the correct syntax?
UPDATE 1
Changing the method definition to:
#doSomething[T](myInnerObj: MyObject[T]#MyInnerObject)
gives further errors:
no type parameters for method doSomething: (myInnerObj:[T]#MyInnerObject)play.twirl.api.HtmlFormat.Appendable exist so that it can be applied to arguments (myObj.MyInnerObject)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : myObj.MyInnerObject
required: MyObject[?T]#MyInnerObject
It would seem that the Twirl templating engine does not support this syntax currently, although I'm not 100% sure.

I can solve the problem by removing the doSomething method completely...
#*******************************************
* My helper
*******************************************#
#(myObj: some.namespace.MyObject[_])
#import some.namespace.MyObject
#for(myInnerObj <- myObj.getInnerObjects()) {
<div>#myInnerObj.getSomeProperty()</div>
}
But I am bout 10% happy with the solution... It works at least but it feels very restricting that I cannot delegate to methods to help keep my code maintainable. By the look of the comments the problem seems to be a limitation in Twirl, not allowing type arguments for functions in views.
Note: I have accepted this answer as it removes the original problem of the exception however this is only because the solution I want doesn't exist... yet.

Related

Better way to do class type alias?

From time to time, I would like to call a class differently depending on the context or to reduce duplication.
Let's assume, I have the following classes defined:
// in file a.dart
class A {
final String someprop;
A(this.someprop)
}
// in file b.dart
abstract class BInterface {
String get someprop;
}
class B = A with EmptyMixin implements BInterface;
For this syntax to check out, I have to define EmptyMixin so that the syntax is OK.
Do you know of a better/prettier way to do this "aliasing" in Dart?
I'm afraid the way you're doing it is the prettiest way to do this at the moment. There is a very old, but still open and active issue: https://github.com/dart-lang/sdk/issues/2626 that proposes the typedef B = A; syntax for aliasing types.

AngelScript - Avoid implicit default constructor from running

I'm currently testing some simple AngelScript stuff, and noticed something I find a bit strange when it comes to how objects are initialized from classes.
Let's say I define a class like this:
class MyClass {
int i;
MyClass(int i) {
this.i = i;
}
}
I can create an object of this class by doing this:
MyClass obj = MyClass(5);
However it seems I can also create an object by doing this:
MyClass obj;
The problem here is that obj.i becomes a default value as it is undefined.
Additionally, adding a default constructor to my class and a print function call in each one reveals that when I do MyClass obj = MyClass(5); BOTH constructors are called, not just the one with the matching parameter. This seems risky to me, as it could initialize a lot of properties unnecessarily for this "ghost" instance.
I can avoid this double-initialization by using a handle, but this seems more like a work-around rather than a solution:
MyClass# obj = MyClass(5);
So my question sums up to:
Can I require a specific constructor to be called?
Can I prevent a default constructor from running?
What's the proper way to deal with required parameters when creating objects?
Mind that this is purely in the AngelScript script language, completely separate from the C++ code of the host application. The host is from 2010 and is not open-source, and my knowledge of their implementation is very limited, so if the issue lies there, I can't change it.
In order to declare class and send the value you choose to constructor try:
MyClass obj(5);
To prevent using default constructor create it and use:
.
MyClass()
{
abort("Trying to create uninitialized object of type that require init parameters");
}
or
{
exit(1);
}
or
{
assert(1>2,"Trying to create uninitialized object of type that require init parameters");
}
or
{
engine.Exit();
}
in case that any of those is working in you environment.
declaring the constructor as private seems not to work in AS, unlike other languages.

Unity3D & YamlDotNet Deserializing Data into Monobehaviour-derived classes

I'm trying to serialize data into / from my classes, derived from MonoBehaviour, which cannot be created from client code (e.g., with the new keyword), but rather must be created by a Unity3D-specific method, GameObject.AddComponent<T>(). How can I use the YamlDotNet framework to populate my classes with values without having to create an adapter for each one? Is there some sort of built-in adapter that I can configure, such that YamlDotNet doesn't instantiate the class it's trying to serialize to?
A typical file might contain a mapping of items, e.g.,
%YAML 1.1
%TAG !invt! _PathwaysEngine.Inventory.
%TAG !intf! _PathwaysEngine.Adventure.
---
Backpack_01: !invt!Item+yml
mass: 2
desc:
nouns: /^bag|(back)?pack|sack|container$/
description: |
Your backpack is only slightly worn, and...
rand_descriptions:
- "It's flaps twirl in the breeze."
- "You stare at it. You feel enriched."
MagLite_LR05: !invt!Lamp+yml
cost: 56
mass: 2
time: 5760
desc:
nouns: /^light|flashlight|maglite|lr_05$/
description: |
On the side of this flashlight is a label...
(Type "light" to turn it on and off.)
...
Where the tags are the fully specified class names of my Items, e.g., PathwaysEngine.Inventory.Lamp+yml, PathwaysEngine is the namespace I use for my game engine code, Inventory deals with items & whatnot, and Lamp+yml is how the compiler denotes a nested class, yml inside Lamp. Lamp+yml might look like this:
public partial class Lamp : Item, IWearable {
public new class yml : Item.yml {
public float time {get;set;}
public void Deserialize(Lamp o) {
base.Deserialize((Item) o);
o.time = time;
}
}
}
I call Deserialize() on all objects that derive from Thing from Awake(), i.e., once the MonoBehaviour classes exist in the game. Elsewhere, I've already created a pretty complicated Dictionary filled with objects of type Someclass+yml, and then Deserialize takes an instance of the real, runtime class Someclass and populates it with values. There's got to be a cleaner way to do this, right?
How can I:
Tell the Deserializer what my classes are?
See the second edit for a good solution for the above issue
Get the data without it attempting to create my MonoBehaviour-derived classes?
Edit: I've since worked at the problem, and have found out a good way of dealing with custom data (in my particular case of trying to parse regexes out of my data, and having them not be considered strings & therefore, un-castable to regex) is to use a IYamlTypeConverter for that particular string. Using YamlDotNet with Unity3D MonoBehaviours, however, is still an issue.
Another Edit: The above examples use a pretty ugly way of determining types. In my case, the best thing to do was to register the tags first with the deserializer, e.g.,
var pre = "tag:yaml.org,2002:";
var tags = new Dictionary<string,Type> {
{ "regex", typeof(Regex) },
{ "date", typeof(DateTime) },
{ "item", typeof(Item) }};
foreach (var tag in tags)
deserializer.RegisterTagMapping(
pre+tag.Key, tag.Value);
Then, I use the !!tag notation in the *.yml file, e.g.,
%YAML 1.1
---
Special Item: !!item
nouns: /thing|item|object/
someBoolean: true
Start Date: !!date 2015-12-17
some regex: !!regex /matches\s+whatever/
...
You can pass a custom implementation of IObjectFactory to the constructor of the Deserializer class. Every time the deserializer needs to create an instance of an object, it will use the IObjectFactory to create it.
Notice that your factory will be responsible for creating instances of every type that is deserialized. The easiest way to implement it is to create a decorator around DefaultObjectFactory, such as:
class UnityObjectFactory : IObjectFactory
{
private readonly DefaultObjectFactory DefaultFactory =
new DefaultObjectFactory();
public object Create(Type type)
{
// You can use specific types manually
if (type == typeof(MyCustomType))
{
return GameObject.AddComponent<MyCustomType>();
}
// Or use a marker interface
else if (typeof(IMyMarkerInterface).IsAssignableFrom(type))
{
return typeof(GameObject)
.GetMethod("AddComponent")
.MakeGenericMethod(type)
.Invoke();
}
// Delegate unknown types to the default factory
else
{
return DefaultFactory(type);
}
}
}

How do I cast to an interface an object may implement?

I have the following classes & interfaces:
export interface IBody {
body : ListBody;
}
export class Element {
// ...
}
export class Paragraph extends Element implements IBody {
// ...
}
export class Character extends Element {
// ...
}
I have code where I will get an array of Element derived objects (there are more than just Paragraph & Character). In the case of those that implement IBody, I need to take action on the elements in the body.
What is the best way to see if it implements IBody? Is it "if (element.body !== undefined)"?
And then how do I access it? "var bodyElement = <IBody> element;" gives me an error.
C:/src/jenova/Dev/Merge/AutoTagWeb/client/layout/document/elements/factory.ts(34,27): error TS2012: Cannot convert 'Element' to 'IBody':
Type 'Element' is missing property 'body' from type 'IBody'.
Type 'IBody' is missing property 'type' from type 'Element'.
thanks - dave
An interface in TypeScript is a compile-time only construct, with no run-time representation. You might find section 7 of the TypeScript specification interesting to read as it has the complete details.
So, you can't "test" for an interface specifically. Done correctly and completely, you generally shouldn't need to test for it as the compiler should have caught the cases where an object didn't implement the necessary interface. If you were to try using a type assertion:
// // where e has been typed as any, not an Element
var body = <IBody> e;
The compiler will allow it without warning as you've asserted that the type is an IBody. If however, e were an Element in scope, the compiler as you've shown will check the signature of the Element and confirm that it has the properties/methods declared by IBody. It's important to note that it's checking the signature -- it doesn't matter that it may not implement IBody as long as the signature matches up.
Assuming that Element has a signature that matches IBody, it will work. If it does not, you'll get the compiler error you're receiving. But, again, if it's declared as any, the assertion will pass and at run-time, unless the type has the methods defined on IBody, the script will fail.
As your Element is the base class, you cannot check for IBody. You could declare an argument as any:
function someFeature(e: any) {
}
And then assert that the IBody is present:
function someFeature(e: any) {
var body :IBody = <IBody> e;
// do something
}
However, if you do need a run-time check, you'd need to look for the function on the prototype or as a property before using it. While that could be misleading in some cases, the interface in TypeScript also may not have caught the mismatch either. Here's an example of how you could check for the existence of a specific function.
It might look like this:
function someFeature(e: any) {
var body = <IBody> e;
if (typeof (body.someFunctionOnBodyInterface) === "undefined") {
// not safe to use the function
throw new Error("Yikes!");
}
body.someFunctionOnBodyInterface();
}

Subclassing native objects: instanceof not working properly

I'm trying to subclass the native JS Error object in CoffeeScript to get specialized error types, but i found that the instanceof does not work correctly if i don't define a constructor in the subclasses:
class SimpleError extends Error
class EmptyConstructorError extends Error
constructor: ->
class SuperConstructorError extends Error
constructor: ->
super
new SimpleError instanceof SimpleError # -> false
new EmptyConstructorError instanceof EmptyConstructorError # -> true
new SuperConstructorError instanceof SuperConstructorError # -> true
The problem seems to be caused by how the generated JS constructor functions are defined. When i don't define a constructor in CoffeeScript:
SimpleError = (function(_super) {
__extends(SimpleError, _super);
function SimpleError() {
return SimpleError.__super__.constructor.apply(this, arguments);
}
return SimpleError;
})(Error);
And when i do define a constructor in CoffeeScript:
SuperConstructorError = (function(_super) {
__extends(SuperConstructorError, _super);
function SuperConstructorError() {
SuperConstructorError.__super__.constructor.apply(this, arguments);
}
return SuperConstructorError;
})(Error);
As you can see, the difference is a simple return in the first case. I don't understand why this makes any difference in the instanceof behavior though, as the super constructor is just being applied to the this object (i.e. the super constructor is not being called with new), but then again i don't understand a whole lot of how JS constructors work =P
And the weird thing is that this behavior seems to only happen when subclassing native JS objects. If i subclass CoffeeScript classes everything works as expected.
Any idea of why this might be happening and how could i avoid writing dummy constructors just for the instanceof operator to work correctly?
Thanks!
Update
So the user matyr answered with a link to the commit where this behavior was introduced, but it doesn't quite explain what is happening here, so i'll try to explain that a little bit in case anyone else wonders why this works this way.
The main problem is this inherited nasty "feature" from JavaScript which let us define a constructor function that returns an object other than the one being constructed:
function Foo() {
return {'LOL': 'You fool!'};
}
new Foo() instanceof Foo // -> false
And there is also the fact that some native constructors, like Error, Array, String and whatnot don't need to be called with new: they will just return a new object of the corresponding type if you happen to forget it.
In the end, add these two ugly things together and the result is that you should remember to write class MyError extends Error then constructor: -> super instead of the more intuitive class MyError extends Error if you want the instanceof operator to work properly with MyError. That's because CoffeeScript's implicit constructor will just return whatever the parent constructor returns, and in this case will do return Error.apply(this, arguments) which will just return a shinny new error object instead of the object you passed as the this argument. Yay!
Update 2 (Feb 25 2013)
This problem was fixed in CoffeeScript 1.5.0! =D
Now extending native objects works as expected:
class MyError extends Error
new MyError instanceof MyError # -> true :)
Update 3 (Mar 04 2013)
Aaand it's gone on 1.6.0 =P
For better or worse, the return was added on 1.3.1 to fix #1966 (and #2111).