How do I access an object field via its field name in string form? - macros

I'm figuring out at compile-time the name of a specific field of an object that I want to access. Before I compile, I do not necessarily know which field that is going to be, so I just have that field name as a string. How can I leverage nim's metaprogramming to access that field on the object?

You can write a very simple macro that evaluates to a dot expression (aka object.yourFieldNameString).
Here an example of how that can look like:
import std/[macros]
macro getField*(obj: object, fieldName: static string): untyped =
nnkDotExpr.newTree(obj, ident(fieldName))
This will only work if you know the field at compiletime (aka when you have it as a static string)! Keep that in mind!

Related

How to allow assignment of incompatible Typescript types?

I'm sharing type definitions between my server and front-end. They're defined in a separate npm package that both install. On the front-end, variables holding ObjectIds need to be typed as that but, on the client, I can assume they're always primitive strings.
I've got a number of places on the client that throw:
Type 'ObjectId' is not assignable to type 'string'.
What's the easiest way to deal with this error? Can I tell Typescript to accept string assignment to ObjectId and vice versa on the client? Should I be trying to override the Mongoose definition of ObjectId?
I'm considering an override of the sort
declare global {
export interface MyInterface1 {
variableWithObjectId1: string
}
export interface MyInterface2 {
variableWithObjectId2: string
}
}
I think this is supposed to work. It's the recommended solution for a similar issue but I have yet to make that work.
I'm hoping there is some way to globally transform ObjectId to string when the library is imported into the client.
ObjectId and String are not the same types at all, hence you cannot simply assign from one to the other.
You need to perform proper conversions.
For each of these errors on the client, I'm converting the type to a string like
var stringId = (myVariable as unknown) as string
I wish there was a cleaner way than this so I'm all ears if someone has a suggestion.

Get a static final field in scala with a string reference

Suppose I have a fully qualified reference string:
val location = "org.path.to.some.field"
val foo = getFieldFromString(location)
I want to get the same value as if I did:
import org.path.to.some.field
How do I do this? Does it make sense to use reflection?
I think this might be the way to do it:
Class.forName("org.path.to.some").getField("field").get(null)
One problem is that you do need to know the type of the field in order for this to return something other than AnyRef. The get(null) is because we don't need an instance to get the static field.

Get a type identified by a string in the Scala macros

I have a bunch of strings (essentially names of java.lang. classes and some custom classes). In the macro I need to add the type to the function:
q"""propKey[${resolveType(c)(argType)}]($name, classOf[$argType])"""
where argType is String.
So far I tried q"$argType" - but that adds the weird signature propKey[String("java.lang.Integer")](...)
with c.universe.TypeName- there's no method to get a c.universe.Type instance.
c.mirror.staticClass("java.lang.String").toType

Scala how to get object property value given name of property in string?

I wondering how to get object property value given name of property in string in Scala? I saw examples when you get all fields of object using Reflection and iterate over it. But is it possible to call it without iteration? Or may be there is a way to pass object.field to another function without evaluation and evaluate it there and return result?
Kolmar comment give me right direction to call by name function.

HowTo: Custom Field in Lift-Record-Squeryl

I'm trying to make a EnumListField in Lift/Record/Squeryl, similar to MappedEnumList in LiftMapper. The storage type should be Long/BIGINT. I understand that if I define:
def classOfPersistentField = classOf[Long]
Then Squeryl will know it should create a BIGINT column. And I know it uses setFromAny() to set the value, passing in the Long. The one piece I don't get is:
How will it read the field's value? If it uses valueBox, it will get a Seq[Enum#Value], and it won't know how to turn that into a Long.
How do I tell Squeryl to convert my Seq[Enum#Value] to a Long, or define a "getter" that returns a Long, and that doesn't conflict with the "normal" getter(s)?
you are implementing your validation logic incorrectly. The correct way to validate a Record field is to override
def validations: List[ValidationFunction]
where ValidationFunction is a type alias
type ValidationFunction = ValueType => List[FieldError]
and in your case ValueType == String.
The next issue is your Domain trait. Because your call to validate is inlined into the class definition, it will be called when your field is constructed.