Given class Foo
class Foo
{
public function new(foo:Int, bar:Int, foobar:Int) {}
}
Retrieve number of arguments accepted by new. I've tried using #:rtti - then I tried
for(field in haxe.rtti.Rtti.getRtti(Foo).fields) {
if (field.name == "new") {
trace(field.type);
}
}
The result was promising
**
TestAll.hx:246: CFunction({
length : 3,
h : {
item : {
name : foo,
opt : false,
t : CAbstract(<...>,<...>),
value : null
},
next : {
item : {
name : <...>,
opt : <...>,
t : <...>,
value : null
},
next : {
item : <...>,
next : null
}
}
},
q : {
item : {
name : foobar,
opt : false,
t : CAbstract(<...>,<...>),
value : null
},
next : null
}
},CAbstract(Void,{
length : 0
}))**
So I tried field.type.length.
test/TestAll.hx:246: characters 14-31 : haxe.rtti.CType has no field
length
After a quick glance at http://api.haxe.org/haxe/rtti/CType.html#CFunction ,
I can see
CFunction(args:List<FunctionArgument>, ret:CType)
??? I'm baffled - it contains a List, yet it only returns CType? How to get to the information I want?
Thank you.
PS. I don't want macro solution, this is used inside unit test, and the generation of the construction itself is already macro heavy.
CType is an enum, and CFunction is one of the possible enum values (or "enum constructors").
You can see the source code here: https://github.com/HaxeFoundation/haxe/blob/development/std/haxe/rtti/CType.hx#L42-L51
You'll need to use a switch statement to dive into it and get your list:
switch (field.type) {
case CFunction(args,returnType):
trace(args.length);
default:
// Do nothing
}
To learn more I recommend these manual pages:
Enums
Pattern matching (switch statements)
Related
I had a question regarding plurals in dialog.
Let's say I have a structure
structure (MyStructure) {
property (MyConcept) {
type {EnumConcept} max (Many)
}
}
And a Value dialog for it:
dialog (Value) {
match: MyConcept(this)
if (this == 'ABC') {
switch(plural(this)) {
case (One) { template("single1") }
default { template ("plural1") }
}
}
if (this == 'DEF') {
switch(plural(this)) {
case (One) { template("single2") }
default { template ("plural2") }
}
}
}
By using
Code:
#{value(myStructure.myConcept.plural('Many'))}
I am able to get "plural1" or "plural2" when myStructure has below values and size of myConcept is 1:
myStructure = [
{ myConcept: ABC },
{ myConcept: ABC },
{ myConcept: ABC },
{ myConcept: ABC }
]
When size of myConcept is 2 and myStructure has below values,
myStructure = [
{ myConcept: ABC },
{ myConcept: ABC },
{ myConcept: DEF },
{ myConcept: DEF }
]
using the Code:
#{value(myStructure.myConcept.plural('Many'))}
is giving NLG as
"single1 and single2"
What I want in the NLG:
"plural1 and plural2"
Can someone please help us in giving proper plural NLG for each element of the unique "myConcept" present in the list of "myStructure"?
What I want is to apply plurality to each individual value of an array.
size(myStructure.myConcept) = 2.
I want to apply plural to both the values of myConcept.
I do not think in dialogs we have an for-each kind of thing available.
It's a little hard to tell what's going on in the code above. If this answer isn't helpful, consider sharing the full source code somewhere for live debugging.
You can try something like
#{value(myStructure.myConcept.plural(plural(myStructure.myConcept))}
The docs has an example like:
#{concept(restaurantStyle.plural(plural(restaurant)))}
Source: https://bixbydevelopers.com/dev/docs/reference/ref-topics/el-ref#node-evaluation-functions in the plural(node) section.
I m getting from terraform 12, call a list of values
data "oci_core_instances" "test_instances" {
#Required
compartment_id = "${var.compartment_ocid}"
availability_domain = "${data.oci_identity_availability_domains.ads.availability_domains[0].name}"
}
// numInstances = 3 for my case
locals {
numInstances = length(data.oci_core_instances.test_instances.instances)
}
and i want to iterate like (pseudo code) :
# Output the result single element
output "format_instances_name_state" {
value = "${
for (i=0 ; i< 3; i++)
format("%s=>%s",data.oci_core_instances.test_instances.instances[i].display_name,data.oci_core_instances.test_instances.instances[i].state)
} "
}
how can i do this in terraform ?
i have tried this :
# Output the result single element
output "format_instances_name_state" {
value = "${
for i in local.numInstances :
format("%s=>%s",data.oci_core_instances.test_instances.instances[i].display_name,data.oci_core_instances.test_instances.instances[i].state)
} "
}
but i m getting this error:
Error: Extra characters after interpolation expression
on main.tf line 64, in output "format_instances_state_element_single":
63:
64: for i in local.numInstances :
Expected a closing brace to end the interpolation expression, but found extra
characters.
any ideas ?
It seems like what you really want here is a map from display name to state, in which case the following expression would produce that:
output "instance_states" {
value = {
for inst in data.oci_core_instances.test_instances.instances : inst.display_name => inst.state
}
}
If you really do need that list of strings with => inside for some reason, you can adapt the above to get it, like this:
output "format_instances_state_element_single" {
value = [
for inst in data.oci_core_instances.test_instances.instances : "${inst.display_name}=>${inst.state}"
]
}
In this second case the for expression is marked by [ ] brackets instead of { } braces, which means it will produce a list result rather than a map result.
What is the efficient way to convert struct to a list of strings (list of all its field - name and value)?
For example the following struct:
struct spot_top_s {
%D_LDO_SFS_EN : uint(bits:1);
%D_COMP3P3_ACC_EN : uint(bits:1);
%D_BGCOMP_TRIM : uint(bits:6);
%spot_top_jtagtest_out : bit;
%spot_top_jtagtest_in : bit;
}; // spot_top_s
Indeed a generic code which accepts any struct can be implemented using reflection.
Here is one example of such a code. You can modify it, for example - add to the list only physical fields (by calling "if it.is_physical()"), etc.
extend sys {
get_fields(input_struct : any_struct) : list of string is {
var struct_rf : rf_struct;
struct_rf = rf_manager.get_struct_of_instance( input_struct);
var struct_fields : list of rf_field;
struct_fields = struct_rf.get_fields();
var field_type_rf : rf_type;
var field_value_unsafe : untyped;
for each in struct_fields {
result.add(it.get_name());
var f:= it.get_value_unsafe(input_struct);
field_type_rf = it.get_type();
field_value_unsafe = it.get_value_unsafe(input_struct);
result.add(field_type_rf.value_to_string(field_value_unsafe));
};
};
// usage example:
my_spot_top : spot_top_s;
post_generate() is also {
print get_field(my_spot_top);
};
};
Several resources, e.g. aws_dynamodb_table have repeatable variables. In the case of the aws_dynamodb_table resource, attribute is repeatable which allows you to specify multiple attributes using either of the following syntax
attribute {
name = "UserId"
type = "S"
}
attribute {
name = "GameTitle"
type = "S"
}
attribute {
name = "TopScore"
type = "N"
}
or
attribute = [{
name = "UserId"
type = "S"
}, {
name = "GameTitle"
type = "S"
}, {
name = "TopScore"
type = "N"
}]
I like this interface and want to provide the same flexibility in my modules but I can't seem to find any documentation on how to do it. Is this possible for modules or is it only the built-in resources that can do this.
It looks like that either allows you to provide attribute multiple times as separate maps (which are then merged) or as a list.
You're going to want to take a look at the documentation related to Input Variable Configuration
In particular, you will want to look at the section titled Variable Merging.
I believe you could do something like this for similar behavior (from the docs above, give them a read :P)
foo {
quux="bar"
}
foo {
bar="baz"
}
This would mean foo returns:
{
quux = "bar"
bar = "baz"
}
Hope that helps!
Here's a part of (groovy) class that stores some data in Mongodb:
long save(Object data) {
def customerReference = getNextCustomerReference()
def map = ['customerReference': customerReference, 'data': data, 'created': new Date()]
BasicDBObject basicDBObject = new BasicDBObject(map)
collection.insert(basicDBObject)
customerReference
}
private long getNextCustomerReference() {
1234
}
even though I have explicitly said i want a primitive long, what ends up in the database is an object:
{ "_id" : ObjectId("52f3c0597d844b0fcee29013"), "customerReference" : NumberLong(1234), "data" : "original data", "created" : ISODate("2014-02-06T17:03:21.411Z") }
However, if I change the return type to def for the private method this happens:
{ "_id" : ObjectId("52f3c1477d84698725f50fe5"), "customerReference" : 1234, "data" : "data", "created" : ISODate("2014-02-06T17:07:19.055Z") }
which the behaviour I want (a primitive stored in the db).
Can someone explain this because its baffling. Surely if I go out of my way to define a type, Groovy should try and honour it?
Groovy almost always automatically autoboxes primitive types to their number reference type-equivalent:
long test_long() { 123l }
int test_int() { 123 }
def test_def() { 123 }
def test_def_long() { 123l }
long l = 42l
assert test_long().class == Long.class
assert test_int().class == Integer.class
assert test_def().class == Integer.class
assert test_def_long().class == Long.class
assert l.class === Long.class
If you remove the long return type, the object is autoboxed to java.lang.Integer. Seems your code handles the Integer like a "primitive".
Some time ago Groovy 1.8 introduced primitive type optimization, an internal fallback to use primitive types under the hood in certain situations. This can help in some situations but is an internal performance optimization you can't directly make use of (by using some syntax construct or something like that).
Sometimes you can force a primitive by an explicit cast, but chances are high it will be converted to a reference type along the way through methods calls and stuff.