#2075 Mandatory slot in facet?

JonasL Tue 1 Jan 2013

Hi,

I've quite recently found out about Fantom after being lost in scala-land for the last 6 months looking for a java replacement.

I really like what you've accomplished here, Fantoms syntax i super easy to read and the approach seems very pragmatic.

To the matter: Can a facets slot be made mandatory when using that facet on a slot?

E g

facet class MinLength {
  const Int minLength
}

class User {
  @MinLength { minLength = 10 }
  Str? firstName
  @MinLength
  Str? lastName
}

so that the annotated password slot would get a compile error saying minLength not defined?

brian Wed 2 Jan 2013

There is no way to mark the field of a facet as required today. We could add a new @Required facet used on the facet's field. What do others think about that? Too much complexity? Or justified feature?

andy Wed 2 Jan 2013

Shouldn't non-nullable fields already handle that?

Akcelisto Fri 4 Jan 2013

I offtopic slightly.

I think, default value for non-nulable fields is unconsistency. Compare A#nonNullFieldInt and A#nonNullFieldStr:

class A{
  Int nonNullFieldInt
  Str nonNullFieldStr
}

Output:

Non-nullable field 'nonNullFieldStr' must be assigned in constructor 'make'

But there is no err for A#nonNullFieldInt.

JonasL Fri 4 Jan 2013

I can give some background on this:

I'd like to use this kind of annotations on container classes that are mapped to some ORM framework - partly to verify the created schema against the container class and partly so I can validate in code the length and save a roundtrip to the DB for finding out that the field is too long.

Most (ok, the 2 I found so far :) ORM mapping frameworks works with "simple" types such as Int, Str so remodelling them to some class containing the length and other metadata would break this, plus having the slots as simple types really helps when running unit tests.

Also length of the field is really only interesting when persisting - so its more of a metadata than an actual needed data for the container class.

@Andy - Did a small test on this:

class Testin {
 @ConstFacetWODefaultAssignment
 Int annotatedField
}

facet class ConstFacetWODefaultAssignment {
 const Str lookImNotAssigned
}

class TestTestin : Test {
 Void testUndefinedConstInFacet() {
   t := Testin { }
   echo(t.typeof.fields[0].hasFacet(ConstFacetWODefaultAssignment#))
   verify(true)
  }
}

It fails first at runtime

fan build.fan && fant SmallTestcases::TestTestin
compile [SmallTestcases]
  Compile [SmallTestcases]
 FindSourceFiles [1 files]
   WritePod [file:/home/jonasl/bin/fantom-1.0.63/lib/fan/SmallTestcases.pod]
BUILD SUCCESS [82ms]!

-- Run:  SmallTestcases::TestTestin.testUndefinedConstInFacet...
ERROR: Cannot decode facet SmallTestcases::ConstFacetWODefaultAssignment: 
sys::FieldNotSetErr: SmallTestcases::ConstFacetWODefaultAssignment.lookImNotAssigned
at fan.sys.FieldNotSetErr.make(FieldNotSetErr.java:25)
at fan.sys.FieldNotSetErr.make(FieldNotSetErr.java:22)
at fan.SmallTestcases.ConstFacetWODefaultAssignment.checkFields$ConstFacetWODefaultAssignment(Whatever.fan:6)
at fan.SmallTestcases.ConstFacetWODefaultAssignment.make$(Whatever.fan:6)

Login or Signup to reply.