Iterate enumerated class instances - ceylon

Is there a simple way to iterate over all enumerated instances of a class in Ceylon?
Just like values() for Java enums?
abstract class Suit() of hearts | diamonds | clubs | spades {
shared formal String name;
}
object spades extends Suit() { name => "Spades"; }
object clubs extends Suit() { name => "Clubs"; }
object diamonds extends Suit() { name => "Diamonds"; }
object hearts extends Suit() { name => "Hearts"; }
Lets say I'd like to pick a random suit or I'd like to print all suits by their names.
Edit:
Explicitly adding all suits to an iterable works but we have to list all possible values again.
{Suit+} suits = {spades, clubs, diamonds, hearts};
Can somebody come up with something better?

This can be done now with ClassOrInterface.caseValues:
Suit[] suits = `Suit`.caseValues;
Regarding the returned sequence:
This sequence is ordered and skips any case type to only include case values.

One way is to use the metamodel:
for (caseType in `class Suit`.caseTypes) {
assert (is OpenClassOrInterfaceType caseType);
print(caseType.declaration.name);
}

Related

EF Core 7 can't deserialize dynamic-members in JSON column

I am trying to map my Name column to a dynamic object. This is how the raw JSON data looks (note that this is SQL-morphed from our old relational data and I am not able to generate or interact with this column via EF Core):
{ "en": "Water", "fa": "آب", "ja": "水", ... }
Just to note, available languages are stored in a separate table and thus are dynamically defined.
Through T-SQL I can perfectly interact with these objects eg
SELECT *
FROM [MyObjects]
WHERE JSON_VALUE(Name, '$.' + #languageCode) = #searchQuery
But it seems EF Core doesn't want to even deserialize these objects as whole, let alone query them.
What I get in a simple GetAll query is an empty Name. Other columns are not affected though.
I have tried so far
Using an empty class with a [JsonExtensionData] dictionary inside
Using a : DynamicObject inheritance and implementing GetDynamicMembers, TryGetMember, TrySetMember, TryCreateInstance
Directly mapping to a string dictionary.
Combining 1 & 2 and adding an indexer operator on top.
All yield the same results: an empty Name.
I have other options like going back to a junction table relational which I have many issues with, hardcoding languages which is not really intuitive and might cause problems in the future, using HasJsonConversion which basically destroys the performance on any search action... so I'm basically stuck here with this.
I think currently it's not fully supported:
You can not use dynamic operations on an expression tree like a Select statement because it needs to be translated.
JsonValue and JsonQuery requires a path to be resolved.
If you specify OwnsOne(entity = >entity.owned, owned => owned.ToJson()) and the Json could not be parsed you will get an error.
I suggest this workaround while the EF team improves the functionality.
Create a static class with static methods to be used as decoys in the expression tree. This will be mapped to the server built-in functions.
public static class DBF
{
public static string JsonValue(this string column, [NotParameterized] string path)
=> throw new NotSupportedException();
public static string JsonQuery(this string column, [NotParameterized] string path) => throw new NotSupportedException();
}
Include the database functions on your OnModelCreating method.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDbFunction(
typeof(DBF).GetMethod(nameof(DBF.JsonValue))!
).HasName("JSON_VALUE").IsBuiltIn();
modelBuilder.HasDbFunction(
typeof(DBF).GetMethod(nameof(DBF.JsonQuery))!
).HasName("JSON_QUERY").IsBuiltIn();
/// ...
modelBuilder.Entity(entity => {
//treat entity as text
entity.Property(x => x.Metadata)
.HasColumnType("varchar")
.HasMaxLength(8000);
});
}
Call them dynamically with LINQ.
var a = await _context.FileInformation
.AsNoTracking()
.Where(x => x.Metadata!.JsonValue("$.Property1") == "some value")
.Select(x => x.Metadata!.JsonValue("$.Property2"))
.ToListAsync();
You can add casts or even build anonymous types with this method.
My solution was I added a new class which has KEY and VALUE , which will represent the dictionary i needed :
public class DictionaryObject
{
public string Key { set; get; }
public string Value { set; get; }
}
and instead of having this line in the JSON class :
public Dictionary<string, string> Name { get; set; }
I changed to :
public List<DictionaryObject> Name { get; set; }
Hope it helps.

Serialize Range with Jackson

I have a Range that I need to serialize in a certain format, namely "[lower,upper)". To do so I have written a basic serializer:
public class RangeSerializer extends StdSerializer<Range<?>> {
#Override
public void serialize(final Range<?> value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
if (value != null) {
gen.writeRaw('"');
gen.writeRaw('[');
provider.defaultSerializeValue(value.lowerEndpoint(), gen);
gen.writeRaw(',');
provider.defaultSerializeValue(value.upperEndpoint(), gen);
gen.writeRaw(')');
gen.writeRaw('"');
}
}
(Note that in reality the serializer handles the various possibilities of Range such as closed/open ranges, the possibility of unbounded ranges at either end, etc. but for the purposes of my question that's not relevant so I've removed it to keep the code simple).
My problem is that by falling back to the default serializer for each class I end up with quotes in the wrong place. For example, if I had a Range<String> with an entry "[foo,bar)" then when serializing it I obtain "["foo","bar")". I need the result without quotes around the lower and upper endpoint values.
I understand that the additional quotes are because gen.writeString() in the underlying serializer doesn't realize that it's already in a string. Is there some way to let the generator know this, or an alternative way to achieve what I'm attempting to do?
Note that Range<?> really is generic, so I can't hard-code the serialization of the values. It needs to work for Range<Integer>, Range<String>, Range<DateTime> and anything else.
I was unable to get your approach of using a single generator to serialize everything working. You might be able to use a DelegatingJsonGenerator and hook certain calls, but I decided the way shown below was significantly simpler (at the price of minor performance loss).
Here's a Spock test class demonstrating how I was able to get this working.
#Grab('com.fasterxml.jackson.core:jackson-databind:2.8.1')
#Grab('org.spockframework:spock-core:1.0-groovy-2.4')
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.databind.util.StdConverter
import spock.lang.Specification
import spock.lang.Unroll
class RangeSerializationTest extends Specification {
static class Range<T> {
T lower
T upper
}
#JsonSerialize(converter = RangeConverter)
static interface RangeMixin {
}
static class RangeConverter extends StdConverter<Range, String> {
private static final mapper = new ObjectMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
#Override
String convert(Range value) {
def lower = mapper.convertValue(value.lower, String)
def upper = mapper.convertValue(value.upper, String)
return "[$lower,$upper)"
}
}
#Unroll
def 'range of #lower.class'() {
given:
def mapper = new ObjectMapper()
mapper.addMixIn(Range, RangeMixin)
expect:
mapper.writeValueAsString(new Range(lower: lower, upper: upper)) == expectedJson
where:
lower | upper | expectedJson
'abc' | 'def' | '"[abc,def)"'
123 | 456 | '"[123,456)"'
new Date(123) | new Date(456) | '"[1970-01-01T00:00:00.123+0000,1970-01-01T00:00:00.456+0000)"'
}
}

Partial definition of generic abstract function

In scala is it possible to declare a generic abstract function in a base class and then
provide different concrete implementations in various derived classes like this:
abstract class B {
def foo[T,V](u:T):V
}
class D extends B {
def foo(u:T_0) = {...}
def foo(u:T_1) = {...}
....
}
and likewise for classes D1, D2,... derived from B (with possibly different concrete types T_j)
accross classes D_j in order to use obj.foo(u) and the compiler flags whenever foo is used on an argument of a type for which foo is not defined.
In short the question is: is a class derived from B considered concrete as soon as foo is defined
for at least one concrete type T?
In your example, you can't specialize U and T within D, you have to match the parameters from the base class. You also can't provide individual special cases of an override within a subclass, like a partial function -- a concrete class must provide implementations for each abstract method, covering all parameters.
It seems to me like what you really want is type parameters at the class level, on B itself, so that derived classes specialize those parameters and then the interface of the foo method they inherit becomes specialized accordingly. So, you'd want to do something like:
abstract class B[T, V] {
def foo(u: T): V
}
class D extends B[String, Int] {
def foo(u: String): Int = u.length
}
(You may also find it useful to add variance annotations class B[-T, +V], but that's another story.)

Communication between visitor and visitee

My current project contains a complex object hierarchy. The following structure is a simplified example of this hierarchy for demonstration purposes:
Library
Category "Fiction"
Category "Science Fiction"
Book A (Each book contains pages, not displayed here)
Book B
Category "Crime"
Book C
Category "Non-fiction"
(Many subcategories)
Now, I want to avoid having nested loops all over my code whenever I need some information from the data structure, because when the structure changes I'd have to update all the loops.
So I plan on using the visitor pattern, which seems to give me the flexibility I need. It would look something like this:
class Library
{
void Accept(ILibraryVisitor visitor)
{
IterateCategories(this.categories, visitor);
}
void IterateCategories(
IEnumerable<Category> categorySequence,
ILibraryVisitor visitor)
{
foreach (var category in categorySequence)
{
visitor.VisitCategory(category.Name);
IterateCategories(category.Subcategories, visitor);
foreach (var book in category.Books)
{
// Could also pass in a book instance, not sure about that yet...
visitor.VisitBook(book.Title, book.Author, book.PublishingDate);
foreach (var page in book.Pages)
{
visitor.VisitPage(page.Number, page.Content);
}
}
}
}
}
interface ILibraryVisitor
{
void VisitCategory(string name);
void VisitBook(string title, string author, DateTime publishingDate);
void VisitPage(int pageNumber, string content);
}
I'm already seeing some possible problems though, so I'm hoping you can give me some advice.
Question 1
If I wanted to create a list of book titles prefixed by the (sub)categories it belongs to (e.g. Fiction » Science Fiction » Book A), a simple visitor implementation would appear to do the trick:
// LibraryVisitor is a base implementation with no-op methods
class BookListingVisitor : LibraryVisitor
{
private Stack<string> categoryStack = new Stack<string>();
void VisitCategory(string name)
{
this.categoryStack.Push(name);
}
// Other methods
}
Here I have already run into a problem: I have no clue on when to pop the stack, because I don't know when a category ends. Is it a common approach to split up the VisitCategory method into two methods, like below?
interface ILibraryVisitor
{
void VisitCategoryStart(string name);
void VisitCategoryEnd();
// Other methods
}
Or are there other ways of dealing with structures like this, which have a clear scope with a start and end?
Question 2
Suppose I only want to list the books that were published in 1982. A decorator visitor would separate the filtering from the listing logic:
class BooksPublishedIn1982 : LibraryVisitor
{
private ILibraryVisitor visitor;
public BooksPublishedIn1982(ILibraryVisitor visitor)
{
this.visitor = visitor;
}
void VisitBook(string title, string author, DateTime publishingDate)
{
if (publishingDate.Year == 1982)
{
this.visitor.VisitBook(string title, string author, publishingDate);
}
}
// Other methods that simply delegate to this.visitor
}
The problem here is that VisitPage will still be called for books that are not published in 1982. So the decorator somehow needs to communicate with the visited object:
Visitor: 'Hey, this book isn't from 1982, so please don't tell me anything about it.'
Library: 'Oh ok, then I won't show you its pages.'
The visit methods currently return void. I could change it to return a boolean which indicates whether to visit sub-items, but that feels kind of dirty. Are there common practices for letting the visitee know that it should skip certain items? Or perhaps I should look into a different design pattern?
P.S. If you think these should be two separate questions, just let me know and I'll be happy to split them up.
The Visitor pattern, as described by the GoF book, deals with class hierarchies and not with object hierarchies. To put it simply, adding a new Visitor type acts like adding a new virtual function to the base class and all the children, without touching their code.
The machinery of a Visitor consists of one Visitor::Visit function per class in the hierarchy, and the Accept function in the parent class and in all the descendants. It works by calling Accept(visitor) through a parent class reference. The implementation of Accept in the object that happens to be referenced calls the right kind of Visitor::Visit(this). It is all fully orthogonal to any object hierarchy that may exist between instances of different subclasses of our root class.
In your case, the ILibraryVisitor interface would have a VisitLibrary(Library) method, a VisitCategory(Category) method, a VisitBook(Book) method, and so on, while each of Library, Category, Book and so on would inherit a common base class and reimplement its Accept(ILibraryVisitor) method.
So far so good. But from this point on your implementation seems to get a bit disoriented. A Visitor does not call its own Visit functions! Members of the hierarchy do, Visitor implements these functions for their benefit. So how do we go down the category tree?
Remember that to call Accept(FooVisitor) replaces the method Foo in the root of the hierarchy, and FooVisitor::VisitBar replaces the implementation of bar::Foo . When we want to do something with an object, we call its methods. don't we? So let's do it (in pseudocode).
class LibraryVisitor : ILibraryVisitor
{
IterateChildren (List<ILibraryObject> objects) {
foreach obj in objects {
obj.Accept(this);
}
}
IterateSubcategories (Category cat) {
stack.push (cat); # we need a stack here to build a path
IterateChildren (cat.children); # both books and subcategories
stack.pop();
}
VisitLibrary (Library) = abstract
VisitCategory (Category) = abstract
VisitBook (page) = abstract
VisitPage (Page) = abstract
}
class MyLibraryVisitor : LibraryVisitor {
VisitLibrary (Library l ) { ... IterateChildren (categories) ... }
VisitCategory (Category c) = { ... IterateSubcategories (c) ... }
VisitBook (Book) = { ... IterateChildren (pages) ... }
VisitPage (Page) = { ... no children here, end of walk ... }
}
Note the ping-pong action between Visit and Accept. Visitor calls Accept on the children of the current visitee, the children call Visitor::Visit back, and Visitor calls Accept on their children etc.
This is how your second question is answered:
class BooksPublishedIn1982 : LibraryVisitor
{
VisitBook (Book b) {
if b.publishedIn (1982) {
IterateChildren(b.pages)
}
}
}
Once again, it is apparent that the tree walk and the visitor machinery have just about nothing to do with each other.
I have left the decision of iterating or not iterating children entirely with each Visit implementation. This need not be the case, you can easily split each VisitXYZ into two functions, VisitXYZProper and VisitXYZChildren. By default, VisitXYZ will call both and each concrete visitor may override that decision.

OOP Proper use of interfaces in AS3

I'm designing a framework and in the process I have come across an interesting but most likely basic problem. I have a base class called CoreEngine and two other classes that extend it: CoreEngine1 and CoreEngine2. I created an interface that each of these classes would implement to increase the flexibility of my project. However, I have a problem... The definition of my methods in the interface do not match the definition in each inherited class! Each class must implement the following method:
function get avatar():AvatarBase;
The problem is that CoreEngine1 and CoreEngine2 expect a different type of avatar:
CoreEngine1
function get avatar():AvatarScaling
CoreEngine2
function get avatar():AvatarPlatform
As you can see, the return type for avatar in CoreEngine1 and CoreEngine2 do NOT match the type as specified in the interface. I was hoping that since both AvatarScaling and AvatarPlatform inherit AvatarBase that I wouldn't have a problem compiling. However, this is not the case. According to Adobe's documentation, the types MUST match the interface. I am trying to follow one of the core concepts of object oriented programming to extend the flexibility of my framework: "Program to an interface rather than an implementation". The first thing that comes to my mind is that the return type of the accessor method should be of an interface type (Maybe I just answered my own question).
I'm certain this is a common problem others have run into before. Architecturally, what do you think is the best way to solve this problem? Thanks in advance!
Regards,
Will
This is a limitation of how interfaces work and are declared.
If there's inheritance that can happen with the return types, as you've described with AvatarBase and subclasses, then I think the right approach is to make the return type the lowest common denominator and just handle the resulting object on the other end. So, if you're dealing with a CoreEngine1 object, you know you can cast the result from AvatarBase to AvatarScaling. Alternately, if you don't know the object type that you are calling get avatar() on, then you can type check the returned value. The type check would then only be needed if you're looking to call a method that exists on AvatarScaling but not on AvatarBase. I don't think returning an interface type will buy you much in this case because the only things that interface can implement would be things that all forms of Avatar share, which wouldn't be any different than methods in AvatarBase.
Like HotN and Dinko mentioned, it would be best to allow get avatar() to return AvatarBase allways and then cast the returned object as the concrete subclass.
Using Dinko's example:
public /* abstract */ class CoreEngine
{
public /* abstract */ function get avatar():AvatarBase {}
}
public function CoreEngine1 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarScaling(); }
}
public function CoreEngine2 extends CoreEngine
{
override public function get avatar():AvatarBase { return new AvatarPlatform(); }
}
public /* abstract */ class AvatarBase {}
public class AvatarScaling extends AvatarBase
{
public function someAvatarScalingMethod():void {}
}
public class AvatarPlatform extends AvatarBase
{
public function someAvatarPlatformMethod():void {}
}
To use a method from AvatarScaling, cast the returned object:
var c1:CoreEngine1 = new CoreEngine1();
var avatarScaling:AvatarScaling = AvatarScaling(c1.avatar());
avatarScaling.someAvatarScalingMethod();
hth
I think you answered your own question... the return type would still be AvatarBase, you need to follow the signature that you specified in the interface... but you can technically return ANY descendent of AvatarBase in that function. So doing something like
return new AvatarScaling();
in CoreEngine1 would be perfectly acceptable.
Of course in your calling function you will get back an AvatarBase instance, and you will have to know what this is in order to cast to a specific subclass.
CoreEngine1 ce1 = new CoreEngine1();
AvatarScaling avatar = ce1.avatar() as AvatarScaling;