How to get a property by this name in String? - dart

I want to access to a property by the name si string format.
If I have a class like that:
class PrefsState {
String a;
PrefsState({
this.a,
})
How can I do something like that:
PrefsState test= PrefsState(a: "it is a test");
String key = "a";
print(test[key]);
Of course is not working. There is a way to do that in Dart ?

Unfortunately, you cannot use reflection/mirrors in flutter.
What you can do, which is tedious, is use maps.
class PrefsState {
String a;
const PrefsState({ this.a, });
dynamic getProp(String key) => <String, dynamic>{
'a' : a,
}[key];
}
It's probably better to build the map in the constructor, but if you want const constructors then you'll have to settle for this. Likely won't make much of a difference unless you have a million parameters anyway. Then you use it like so:
PrefsState test= PrefsState(a: "it is a test");
String key = "a";
print(test.getProp(key));
I don't think there is a less cumbersome way of doing this, but would love to be proven wrong :-)

You can do it with mirrors, but mirrors don't work in dart2js or flutter. You can use code builders to get at this, but the real question is what is your need for this?

Related

Dart accessing class fields like map values

I was wondering if it was possible to access the values of fields in an object with their names in a manner analogous to accessing values in a map with the key names. For example, something like this
void main() {
MyData d=MyData();
List<String> fieldNames=['a','b','c'];
for(var name in fieldNames){
print('This is the value of the $name field: ${d[name]}}');
}
}
class MyData{
String a='A';
String b='B';
String c='C';
}
Of course, this doesn't work because Dart doesn't quite know what to make of d[name] because d is an object. But if d was a map, it would work. Like this.
void main() {
Map d=myData;
List<String> fieldNames=['a','b','c'];
for(var name in fieldNames){
print('This is the value of the $name field: ${d[name]}}');
}
}
Map myData={
'a':'A',
'b':'B',
'c':'C',
};
So my question is this. If I have a class, is there any way to treat it like a Map in the situations where I might want to refer to several of the field values indirectly via their names like I tried to do above? Or is this sort of trick not possible in a compiled language like Dart?
The short answer is "no". The longer answer is "noooooooo". :)
But seriously, the namespace of your program code is very separate from the data values that are managed by your code. This isn't JavaScript, where we can freely flow from code to data to code again.

How to prevent getter or function from recalculate every time?

Let say I have class like this
class OrderInfo {
final String orderId;
final String status;
final DateTime orderDateTime;
final DateTime? deliverDateTime;
final String? restaurantTitle;
OrderInfo({
required this.orderId,
required this.status,
required this.orderDateTime,
required this.deliverDateTime,
required this.restaurantTitle,
});
// and a getter
Something get something {
// Very long code that I don't want to recalculate
return something;
};
}
Since all fields is final, so there's no point to recalculate (return value will be the same).
I tried create field like this.
late Something something = () {
// Very long code that I don't want to recalculate
return something;
}();
But I'm not sure this is correct way to do.
Is there other method or this is fine?
The late field is fine. I'd make it final, unless you want to allow overwriting the value.
I'd probably extract the computation function into a named helper function, like:
class OrderInfo {
late final Something something = _computeSomething();
...
Something _computeSomething() {
// Very long code that I don't want to recalculate
return something;
}
}
Keeping the computation on the side makes the variable declaration more readable, and it allows you to reuse _computeSomething if you want to, but otherwise the effect is the same.
If the Something cannot be null, you can also implement your own late variable:
class OrderInfo {
Something? _something;
...
Something get something => _something ??= _computeSomething();
...
}
The only advantage over a late final .. = ... is that it allows you to check whether the _something has been computed or not.
In some cases that's useful. Say the computation allocates a resource, and you want to release that resource later. If you just use a late variable to store the allocated value, all you can do is read that variable or not. Reading it will allocate the resource, if it wasn't already, and then you have to release it.
Using a nullable variable, you can check whether there is something to release, and do nothing if not.
In general, if you ever need to know whether a late variable has been initialized, consider not using late to begin with, because late hides the "is initialized" bit from you.
Hiding details is what makes the late final something = ...; so nice and short, so using late final is fine when you don't need to know.
(I'd generally recommend against exposing late public fields that are not final, or that do not have an initializing expression, because that will also expose a setter for the field. It either exposes the potentially uninitialize field to your users, risking it throwing when read, or it exposes a setter in your API that users cannot call anyway. A late final variable with an initializer expression is great, because it doesn't have a setter, and it is always initialized when it's read.)
save result into a final variable, then the getter only take the result, it will not recalculate :
class OrderInfo {
final String orderId;
final String status;
final DateTime orderDateTime;
final DateTime? deliverDateTime;
final String? restaurantTitle;
late final Something _somethingFinal;
OrderInfo({
required this.orderId,
required this.status,
required this.orderDateTime,
required this.deliverDateTime,
required this.restaurantTitle,
}){
_somethingFinal = _calculateSomthing();
}
// and a getter
Something get something {
// Very long code that I don't want to recalculate
return _somethingFinal;
}
Something _calculateSomthing(){
return Something();
}
}
class Something{
}

Way to defensive check value assigned to public const variable in immutable class in C++17?

Coming back to C++ after a hiatus in Java. Attempting to create an immutable object and after working in Java, a public const variable seems the most sensible (like Java final).
public:
const int A;
All well and good, but if I want to defensive check this value, how might I go about it. The code below seems strange to me, but unlike Java final members, I can't seem to set A in the constructor after defensive checks (compiler error).
MyObj::MyObj(int a) : A(a) {
if (a < 0)
throw invalid_argument("must be positive");
}
A public const variable for A seems like a clearer, cleaner solution than a getter only with a non const int behind it, but open to that or other ideas if this is bad practice.
Your example as it stands should work fine:
class MyObj {
public:
const int var;
MyObj(int var) : var(var) {
if (var < 0)
throw std::invalid_argument("must be positive");
}
};
(Live example, or with out-of-line constructor)
If you intend that MyObj will always be immutable, then a const member is
probably fine. If you want the variable to be immutable in general, but still have the possibility to overwrite the entire object with an assignment, then better to have a private variable with a getter:
class MyObj {
int var;
public:
MyObj(int var) : var(var) {
if (var < 0)
throw std::invalid_argument("must be positive");
}
int getVar() const { return var; }
};
// now allows
MyObj a(5);
MyObj b(10);
a = b;
Edit
Apparently, what you want to do is something like
MyObj(int var) {
if (var < 0)
throw std::invalid_argument("must be positive");
this->var = var;
}
This is not possible; once a const variable has a value it cannot be changed. Once the body ({} bit) of the constructor starts, const variables already have a value, though in this case the value is "undefined" since you're not setting it (and the compiler is throwing an error because of it).
Moreover, there's actually no point to this. There is no efficiency difference in setting the variable after the checks or before them, and it's not like any external observers will be able to see the difference regardless since the throw statement will unroll the stack, deconstructing the object straight away.
Generally the answer by N. Shead is the regular practice - but you can also consider:
Create domain-specific types and use them instead of general primitives. E.g., if your field is a telephone number, have a type TelephoneNumber which, in its constructor (or factory), taking a string, does all the telephone number validation you'd like (and throws on invalid). Then you write something like:
class Contact {
const TelephoneNumber phone_;
public:
Contact(string phone) : phone_(phone) { ... }
...
When you do this the constructor for TelephoneNumber taking a string argument will be called when initializing the field phone_ and the validation will happen.
Using domain-specific types this way is discussed on the web under the name "primitive obsession" as a "code smell".
(The problem with this approach IMO is that you pretty much have to use it everywhere, and from the start of your project, otherwise you start having to have explicit (or implicit) casting all over the place and your code looks like crap and you can never be sure if the value you have has been validated or not. If you're working with an existing codebase it is nearly impossible to retrofit it completely though you might just start using it for particularly important/ubiquitous types.)
Create validation methods that take and return some value, and which perform the validation necessary - throwing when invalid otherwise returning its argument. Here's an example validator:
string ValidatePhoneNumber(string v) {
<some kind of validation throwing on invalid...>
return v;
}
And use it as follows:
class Contact {
const string phone_;
public:
Contact(string phone) : phone_(ValidatePhoneNumber(phone)) { ... }
I've seen this used when an application or library is doing so much validation of domain-specific types that a small library of these domain-specific validator methods has been built up and code readers are used to them. I wouldn't really consider it idiomatic, but it does have the advantage that the validation is right out there in the open where you can see it.

Print detailed structure / type information of a variable's value

I wonder, if a dart or flutter method exists, which returns complete type information about the structure of a variable's value as a string.
E.g., if some print( someValue.toString() ); emits this
{"user":"userName","state":"valid"}
I don't know if it is a Map or a String.
But how do I get a string, which describes a variable's value / structure?
Something, that's like PHP's print_r(), which print stuff like this:
Array
(
[a] => Apfel
[b] => Banane
[c] => Array
(
[0] => x
[1] => y
[2] => z
)
)
There is nothing like print_r() available natively in Dart.
However, it would be possible to use the following functionalities to build e.g. a function like print_r() from PHP.
You can evaluate the type of someValue using runtimeType.
String someValueType = someValue.runtimeType.toString();
String someValueString = someValue.toString();
If you want to compare, you can also use is. More on that here.
Dart is a strongly typed language, which means that you could also enforce types (List a; String b), which makes a function like print_r() redundant for Dart.
If it is about server-side code you can use reflection to create a function that produces such an output for every value.
If it is about your own classes, you can implement toString() to make the objects render themselves this way when they are printed
class Person {
Foo(this.firstName, this.lastName);
String firstName;
String lastName;
#override
String toString() => '''
firstName: $firstName
lastName: $lastName
''';
}
print(new Person('John', 'Doe'));
Best way to do is
print(”$someValue“);
It will return a structured string which similar to JSON.

How do I dispatch a constructor on a class in Dart?

I previously had the following code, it works fine. (note that Card, SearchResults, Quiz all extend Persistable, and Persistable contains the constructor .fromMap.
Persistable fromString(String value){
Map<String, dynamic> m = parse(value);
switch(m['type']){
case 'card':
return new Card.fromMap(m);
case 'searchresults':
return new SearchResults.fromMap(m);
case 'quiz':
return new Quiz.fromMap(m);
}
}
It was a bit wordy, so I thought I would break it down into two parts. I first have this:
static final Map<String, Persistable> lookup =
{'card': Card,
'searchresults': SearchResults,
'quiz': Quiz };
Seems reasonable, but then when I try to redefine the method, I get confused.
Persistable fromString(String value){
Map<String, dynamic> m = parse(value);
String type = m['type'];
Persistable p = lookup[type];
... Confused, this can't be right
... ultimately want to "return new p.fromMap(m)";
}
Persistable p really means a instance of class Persistable. How do I type my lookup map so that its values are of the class Persistable, so that I can call their .fromMap constructors?
First of all I think your initial approach is perfectly valid and should not be cast away owing simply to its verbosity.
I believe alternative approaches introduce additional complexity and are justified only if you are really in need of dynamic dispatch. (For example if you write library for persistency and you wish to add ability to register arbitrary class for persistency for clients of library)
If dynamic dispatch is a must for you I believe there is two main possibility:
- Reflection API. Recently reflection library got sync API, so this way is now much more affordable then before. I believe there always will be some cost incurred by reflection anyway.
- Use core DART functionality.
With the second approach you may use some sort of trick to imitate constructor call dynamically.
For instance you may store in map not Type variable but function which returns instance of required class:
So your code may look something like
static final Map<String, Function> lookup = new Map<String, Function>
static void registerClass(String className, factory) {
lookup[className] = factory;
}
static Persistable getInstance(String className, Map map){
return lookup[className](map);
}
And on client side:
....
registerClass('quiz', (map)=> new Quiz.fromMap(map));
registerClass('card', (map)=> new Card.fromMap(map));
(Attention - I did not test this)
You may look for working sample code for that approach in https://github.com/vadimtsushko/objectory

Resources