How do I pass a docstring to pybind11::def_property_readonly? - pybind11

I am trying to add a documented readonly property to a class in a python extension defined using pybind11. Usually this is done by adding a string argument to the define call. However, when I add a string argument to the readonly property definition call, I get template compile errors.
Compiles but doesn't have a docstring:
[...]
.def_property_readonly(
"property_name",
[](){ return ""; })
[...]
Has a docstring but doesn't compile:
[...]
.def_property_readonly(
"property_name",
[](){ return ""; },
std::string("docstring"))
[...]

You have to pass a const char * instead of a std::string.
[...]
.def_property_readonly(
"property_name",
[](){ return ""; },
"const char docstring")
[...]

Related

Ethers how to encode data to bytes parameters

I'm trying to test a piece of generic solidity code, I'm trying to figure out how to encode data properly for bytes parameters.
I have a function in a smart contract which looks like so:
function validateAdditionalCalldata(bytes calldata resolverOptions) external view;
function resolve(uint256 amountIn, bytes calldata resolverOptions) public override returns (uint256 amountOut) {
// Decode the additional calldata as a SwapResolverOptions struct
(SwapResolverOptions memory swapResolverOptions) = abi.decode(resolverOptions, (SwapResolverOptions));
return resolveImplementation(amountIn, swapResolverOptions);
}
This solidity code will generate code which takes in a PromiseOrValue<BytesLike>:
resolve(
amountIn: PromiseOrValue<BigNumberish>,
resolverOptions: PromiseOrValue<BytesLike>,
overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;
export type SwapResolverOptionsStruct = {
path: PromiseOrValue<BytesLike>;
deadline: PromiseOrValue<BigNumberish>;
amountIn: PromiseOrValue<BigNumberish>;
amountOutMinimum: PromiseOrValue<BigNumberish>;
inputTokenAddress: PromiseOrValue<string>;
targetAddress: PromiseOrValue<string>;
destinationAddress: PromiseOrValue<string>;
};
I'm wondering how I can encode a specific parameter so I can pass it along to ethers. In typescript I have a set of options that looks like this:
const resolverOptions: SwapResolverOptionsStruct = {
path: '0x00',
//This parameter will be removed in the next deployment
deadline: BigNumber.from(1000),
amountIn: BigNumber.from(100000000),
amountOutMinimum: BigNumber.from(0),
inputTokenAddress: WMATIC_MUMBAI,
destinationAddress: owner.address,
targetAddress: ADDRESS_ZERO,
};
I'm trying to encode this parameters in the following way:
import { defaultAbiCoder } from "#ethersproject/abi";
encodedResolverOptions = defaultAbiCoder.encode(
['SwapResolverOptionsStruct'],
[resolverOptions]
);
However when I try to encode it gets and error:
Error: invalid type (argument="type", value="SwapResolverOptionsStruct",
Note: in my paticular use case I cannot just encoded the whole function call.
I would like to pass my data to the validateAdditionalCalldata how ever the parameter is PromiseOrValue<BytesLike>
How can I encoded my resolverOptions so I can pass it as bytes?
I figured out a few way to do this. I'll list each one:
Resolve the type params using ethers and get function. (if there is a function which has your type in it)
const functionFragment = swapResolverInterface.getFunction("resolveImplementation");
encodedResolverOptions = defaultAbiCoder.encode(
[functionFragment.inputs[1]],
[resolverOptions]
);
Resolve it from an object and a method signature with parameter names:
encodedResolverOptions = defaultAbiCoder.encode(
["(bytes path,uint256 deadline,uint256 amountIn,uint256 amountOutMinimum,address inputTokenAddress,address destinationAddress,address targetAddress)"],
[resolverOptions]
);
Resolve it as an array from the method signature without names Note: this assumes the object was declared in the same order as the parameters, alternatively you can manually construct the array:
encodedResolverOptions = defaultAbiCoder.encode(
["(bytes,uint256,uint256,uint256,address,address,address)"],
[Object.values(resolverOptions)]
);

Dart Class with ":" vs Dart Class without [duplicate]

I have a class that I am creating that looks like this:
class Movie {
final String title, posterPath, overview;
Movie(this.title, this.posterPath, this.overview);
Movie.fromJson(Map json) {
title = json["title"];
posterPath = json["poster_path"];
overview = json['overview';
}
}
I am getting a warning that says that "The final variables 'overview', 'posterPath', & '1' more must be initialized. There are also warnings around each variable saying 'title' can't be used as a setter because it is final.
When I write the constructor using this syntax, the warnings go away:
Movie.fromJson(Map json)
: title = json["title"],
posterPath = json["poster_path"],
overview = json['overview'];
What exactly is going on here?
Dart objects must be fully initialized before anyone gets a reference to the new object. Since the body of a constructor can access this, the object needs to be initialized before entering the constructor body.
To do that, generative Dart constructors have an initializer list, looking similiar to C++, where you can initialize fields, including final fields, but you cannot access the object itself yet. The syntax:
Movie.fromJson(Map json)
: title = json["title"],
posterPath = json["poster_path"],
overview = json['overview'];
uses an initializer list (the list of assignments after the :) to initialize the final instance variables title, posterPath and overview.
The first constructor uses an "initializing formal" this.title to directly put the parameter into the field.
The constructor
Movie(this.title, this.posterPath, this.overview);
is effectively a shorthand for:
Movie(String title, String posterPath, String overview)
: this.title = title, this.posterPath = posterPath, this.overview = overview;
Your constructor can combine all of these and a body:
Movie(this.title, this.posterPath, String overview)
: this.overview = overview ?? "Default Overview!" {
if (title == null) throw ArgumentError.notNull("title");
}
(A const constructor cannot have a body, but it can have an initializer list with some restrictions on the allowed expressions to ensure that they can be evaluated at compile-time).
Dart separates properties initialization from the constructor body.
A constructor has 3 parts :
the name/parameters definition
properties initialization/super call/asserts
A body, similar to a function immediately run on construction
Both the initialization and body parts are optional.
final variables must be initialized on the first 2 parts. They cannot be initialized inside the body.
A full constructor will look like the following :
MyClass(int value)
: assert(value > 0),
property = value,
super();
{
print("Hello World");
}
The main purpose of this initializer part is for body-less constructors which allows const constructors, a dart specific feature. See How does the const constructor actually work? for more details on these.
I just found some documentation around this, & it seams that the second version with the : is what's called the "initializer list" which allows you to initialize instance variables before the constructor body runs.
There is more detail around this in the documentation here.

Flutter required keyword

I don't really understand how required works. For example I've seen this code:
class Test{
final String x;
Test({
required this.x
});
factory Test.initial(){
return Test(x: "");
}
}
But what should required do here? Seems like it makes an optional parameter a non optional parameter.
Update
As of Dart 2.12, the required keyword replaces the #required meta annotation. For detailed info look into the official FAQ. The following answer has been updated to reflect both this and null safety.
Parameters required by default
The parameters of a class constructor or function are required by default.
class Test {
final String x;
Test(this.x);
}
You're not allowed to do this:
final value = Test();
// 1 positional argument(s) expected, but 0 found.
You must do this:
final value = Test('hello');
Optional named parameters
If you surround a parameter with curly braces, though, in addition to becoming a named parameter, it also becomes optional.
Since it's optional, the property must either be nullable like this:
class Test {
final String? x;
Test({this.x});
}
Or it has to have a default value like this:
class Test {
final String? x;
Test({this.x = ''});
}
So now this is ok:
final value = Test();
And so is this:
final value = Test(x: 'hello');
Required named parameters
Sometimes you don't want to allow a parameter to be null and there is no natural default variable. In that case you can add the required keyword in front of the parameter name:
class Test {
final String x;
Test({required this.x});
}
This is not ok anymore:
final value = Test();
// The named parameter 'x' is required, but there's no corresponding argument.
But this is still fine:
final value = Test(x: 'hello');
Dart 2.12 (null safety):
Beginning with Dart 2.12, the #required annotation is now replaced by the required keyword. You should mark your field required if it is mandatory for others to pass some value to it.
For example:
class Foo {
final int a; // Mandatory? Use 'required'
final int b; // Not mandatory? Don't use 'required'
Foo({
required this.a, // Marked 'required'
this.b = 1,
});
}
Usage:
Foo(); // Error: 'a' is required
Foo(a: 0); // Good
Foo(a: 0, b: 1); // Good
#required is an annotation that will create a warning for you to remember that the named parameter is necessary for the class to work as expected.
It will not create compile errors, at least for what I know.
#required bounds you to pass #required marked arguments while creating object of Class. For example, while showing a dialog, you'd mark context as required since, you cannot show dialog without having a valid context. But, you should not overuse it.
Short answer: Named parameters are optional by default in Dart. We prefer them to positional params for ease of use. In this case, the named parameters also might be expected to hold some value all the time (non-nullable) - from initialization itself. Hence, the double effort.
He could use default value initialization of the parameters instead of 'required', if the values were compile-time constants, and that doesn't seem to be the case here.
Positional parameters can be required or optional, which we pass in order when calling. The following is an example of required positional parameters' usage:
class Object{
String name;
int value;
Object(this.name, this.value=100); //auto type inference
}
final one = Object("Name here", 50); // All parameters are needed to call.
Named parameters are another type of optional parameters. Flutter APIs use named parameters and in our UI code, it is preferred to use named parameters instead of positional parameters. Reason being readability and clarity when reading code or calling the constructors later on at several parts of the code. You would have seen this as the case with all Widgets, Styles. For if it were to be positional it would be difficult to keep track of them upon calling with the sheer amount of methods that would be in use, and dynamic type inference could also be at work.
void display({required String name, int value1, int value2=100}) {...;} //named params
display(value1: 50, name: "Calculated name");
NOTE:
If exists, required positional parameters have to come first. Either named or optional positional params can follow(NOT BOTH).
String say(String from, String msg, [String? device]) { //req. pos params and opt pos params.
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
Remove
required
in constructor.
Instead write
final String? x;
So, it becomes as:
class Test{
final String? x;
Test({
this.x
});
factory Test.initial(){
return Test(x: "");
}
}

Using local variables in function built with haxe macro

I have a LangBuilder macro class; it's used to build a langObjects:Map<String, Dynamic> of texts in various languages at compile time, and inject this structure in classes via #:build macro. Every item of the Map has a field for every language supported. So the result is:
#:build(LangBuilder.build())
class Lang{}
trace(Lang.langObjects["hello-world"].en); //outputs "Hello World!"
trace(Lang.langObjects["hello-world"].it); //outputs "Ciao Mondo!"
This works perfectly, but I thought I could make a cleaner job hiding the langObjects structure using a function getLangText with arguments the id of the text (e.g. "hello-world") and the language code (e.g. "it").
So I'm trying to add this function to classes:
public static function getLangText(id:String, lang:String)
Its non-macro version could be expressed as:
public static function getLangText(id:String, lang:String){
var _langObj_id = langObjects[id];
switch(lang){
case "it":
return _langObj_id.it;
case "en":
return _langObj_id.en;
}
return "Missing Translation";
If i translate this function as a macro with this code:
var code = macro {
var _langObj_id = langObjects[$i{"id"}];
switch($i{"lang"}){
case "it":
return _langObj_id.it;
case "en":
return _langObj_id.en;
}
return "Missing translation";
};
var myFunc:Function = {
args: [{
name: "id",
type: TPath({name: "String", pack: []}),
meta: null
},
{
name: "lang",
type: TPath({name: "String", pack: []}),
meta: null
}],
ret: (macro:String),
expr: macro $code
};
fields.push({
pos: Context.currentPos(),
name: "getLangText",
meta: null,
kind: FieldType.FFun(myFunc),
doc: null,
access: [Access.APublic, Access.AStatic]
});
... it works without problems. However I would like to know how it could be written without the switch, to make it more flexible and to learn something about haxe macros. I have seen some examples where fields could be accessed in macros with $p{} or with object.$fieldName. However the haxe manual warns that the second form could be used only for simple identifiers; for example object.${fieldName} would not work.
So I try this code:
var code = macro {
var l:String = $i{"lang"};
var _langObj_id = langObjects[$i{"id"}];
return _langObj_id.$l;
};
The compiler gives an error
Unknown identifier : l
on the line containing return _langObj_id.$l;.
Then i tried to use the $p{} reification:
var code = macro {
var _langObj_id = langObjects[$i{"id"}];
return macro $p{["_langObj_id", $i{"lang"}]};
};
But the error is similar:
Unknown identifier : lang
I can surely change the langObjects structure to Map<String, Map<String, String>> and then change the code to:
var code = macro {
return macro langObjects[$i{"id"}][$i{"lang"}];
};
I think this would work, but now i'm trying to understand why both _langObj_id.$lang and $p{["_langObj_id", $i{"lang"}]} wouldn't work, and what would be the correct way to access a field in a situation like that.
The value of the lang parameter is not known at compile- / macro-time, so I don't see how you could generate a field access expression like langObjects["mytext"].en. At runtime when getLangText() is actually called, lang could be "en", or anything else. So that would still require a switch-case, if-else-chain or reflection to handle all the possible values.
If instead of using being created by a build macro, getLangText() was an expression macro / a macro function, the function call would be evaluated at compile-time, and be replaced with the expression it returns. That would allow you to generate the appropriate field access expression based on the parameters. It could look something like this:
class Macro {
public static var langObjects = ["mytext" => {en: "hello", de: "hallo"}];
public static macro function getLangText(id:String, lang:String) {
return macro {
var langObject = Macro.langObjects[$v{id}];
langObject.$lang;
}
}
}
class Main {
static function main() {
trace(Macro.getLangText("mytext", "en"));
trace(Macro.getLangText("mytext", "de"));
}
}
Compiles to the following on the JS target:
Main.main = function() {
var langObject = Macro.langObjects.get("mytext");
console.log("source/Main.hx:3:",langObject.en);
var langObject1 = Macro.langObjects.get("mytext");
console.log("source/Main.hx:4:",langObject1.de);
};
Perhaps that's what you're looking for? Hard to say without knowing what problem you're trying to solve.

Add method to string class in node.js express.js coffeescript

I want to add some my methods to generic types like string, int etc. in express.js (coffeescript). I am completely new in node. I want to do just this:
"Hi all !".permalink().myMethod(some).myMethod2();
5.doSomething();
variable.doSomethingElse();
How to do this ?
You can add a method to the String prototype with:
String::permaLink = ->
"http://somebaseurl/archive/#{#}"
String::permalink is shorthand for String.prototype.permaLink
You can then do:
somePermalink = "some-post".permaLink()
console.log somePermalink.toUpperCase()
This will call the the "String.prototype.permaLink" function with "this" set to the "some-post" string. The permaLink function then creates a new string, with the string value of "this" (# in Coffeescript) included at the end. Coffeescript automatically returns the value of the last expression in a function, so the return value of permaLink is the newly created string.
You can then execute any other methods on the string, including others you have defined yourself using the technique above. In this example I call toUpperCase, a built-in String method.
You can use prototype to extend String or int object with new functions
String.prototype.myfunc= function () {
return this.replace(/^\s+|\s+$/g, "");
};
var mystring = " hello, world ";
mystring.myfunc();
'hello, world'