Expression.Call and "Ambiguous Match Found" - c#-4.0

I'm trying to write an expression that will call ToString on a property and assign it's value to a local variable. However, calling ToString on a object instance w/ an overload of ToString, causes an exception of "Ambigous Match Found" to be thrown. Here's an example:
var result = Expression.Variable(typeof(string), "result");
var matchTypeParameter = Expression.Parameter(typeof(MatchType), "matchType");
var targetProperty = Expression.Property(leadParameter, target);
var exp = Expression.Block(
//Add the local current value variable
new[] { result },
//Get the target value
Expression.Assign(result, Expression.Call(targetProperty, typeof(string).GetMethod("ToString"), null))
);
How can I call ToString if the instance has overloads for it? Thanks!

Replace:
typeof(string).GetMethod("ToString")
With:
typeof(string).GetMethod("ToString", Type.EmptyTypes)
In other words, get the method named "ToString" that takes zero arguments (empty type array).

Related

Inconsistent error while storing a darray into a Shape

I have a shape like this
const type TFileInfo = shape(
'displayName' => string,
'givenName' => string,
'jobTitle' => string,
'businessPhones' => vec<string>
);
private Person::TFileInfo $person;
Now my constructor of the class looks like so
public function __construct(string $apiresponse) { // instance method
$json = \json_decode($response, /* associative = */ true);
TypeAssert\matches<self::TFileInfo>($json);
$this->person = $json; //OFFENDING LINE
$this->person['businessPhones1'] = "";
}
Now strangely the above code does not throw any error .
If I remove the offending line , then the last line throws a compile time error Expected nothing because the field 'businessPhones1' is not defined in this shape type, and this shape type does not allow unknown fields
What am I missing here ? Is there a better way to assign an API response to a typed variable ?
TypeAssert\matches doesn't prove that its argument is the type you specified, in contrast to the behavior of some other built-ins like is_null which are special-cased in the typechecker. Instead, it coerces the argument and returns it, so you need to move your standalone call to the assignment, i.e. $this->person = TypeAssert\matches<self::TFileInfo>($json);.
You might have expected a type error from the $this->person = $json assignment then, but in fact json_decode and some other unsafe built-in PHP functions are special-cased by the typechecker to be bottom types (convertible to anything) so they could be usable at all before type-assert. It remains this way today: see its type definition in the HHVM source, probably for compatibility.
One other interesting point about this case is that $this->person = $json coerces $this->person to a bottom type as well downstream of the binding. To my understanding, this is a specific behavior of the Hack typechecker to do this for a single level of property nesting, yet it preserves the types for properties of properties (the second example has_error):
<?hh // strict
class Box<T> { public function __construct(public T $v) {} }
function no_error<T>(Box<int> $arg): T {
$arg->v = json_decode('');
return $arg->v;
}
function has_error<T>(Box<Box<int>> $arg): T {
$arg->v->v = json_decode('');
return $arg->v->v;
}

How to use dot(.) to MongoDB(Mongoose) schema as a parameter [duplicate]

It's difficult to explain the case by words, let me give an example:
var myObj = {
'name': 'Umut',
'age' : 34
};
var prop = 'name';
var value = 'Onur';
myObj[name] = value; // This does not work
eval('myObj.' + name) = value; //Bad coding ;)
How can I set a variable property with variable value in a JavaScript object?
myObj[prop] = value;
That should work. You mixed up the name of the variable and its value. But indexing an object with strings to get at its properties works fine in JavaScript.
myObj.name=value
or
myObj['name']=value (Quotes are required)
Both of these are interchangeable.
Edit: I'm guessing you meant myObj[prop] = value, instead of myObj[name] = value. Second syntax works fine: http://jsfiddle.net/waitinforatrain/dNjvb/1/
You can get the property the same way as you set it.
foo = {
bar: "value"
}
You set the value
foo["bar"] = "baz";
To get the value
foo["bar"]
will return "baz".
You could also create something that would be similar to a value object (vo);
SomeModelClassNameVO.js;
function SomeModelClassNameVO(name,id) {
this.name = name;
this.id = id;
}
Than you can just do;
var someModelClassNameVO = new someModelClassNameVO('name',1);
console.log(someModelClassNameVO.name);
simple as this
myObj.name = value;
When you create an object myObj as you have, think of it more like a dictionary. In this case, it has two keys, name, and age.
You can access these dictionaries in two ways:
Like an array (e.g. myObj[name]); or
Like a property (e.g. myObj.name); do note that some properties are reserved, so the first method is preferred.
You should be able to access it as a property without any problems. However, to access it as an array, you'll need to treat the key like a string.
myObj["name"]
Otherwise, javascript will assume that name is a variable, and since you haven't created a variable called name, it won't be able to access the key you're expecting.
You could do the following:
var currentObj = {
name: 'Umut',
age : 34
};
var newValues = {
name: 'Onur',
}
Option 1:
currentObj = Object.assign(currentObj, newValues);
Option 2:
currentObj = {...currentObj, ...newValues};
Option 3:
Object.keys(newValues).forEach(key => {
currentObj[key] = newValues[key];
});

Is there a way to a prevent a String from being interpolated in Swift?

I'm experimenting around the idea of a simple logger that would look like this:
log(constant: String, _ variable: [String: AnyObject]? = nil)
Which would be used like this:
log("Something happened", ["error": error])
However I want to prevent misuse of the constant/variable pattern like the following:
log("Something happened: \(error)") // `error` should be passed in the `variable` argument
Is there a way to make sure that constant wasn't constructed with a string interpolation?
You could use StaticString instead of String:
func log(constant: StaticString, _ variable: [String: AnyObject]? = nil) {
// You can retrieve `String` from `StaticString`
let msg = constant.stringValue
}
let foo = 1
log("test \(foo)") // -> error: cannot invoke 'log' with an argument list of type '(String)'

Is it possible to log variable name in JavaScript?

Is it possible to log variable name (not value) in JavaScript?
var max_value = 4;
console.log(max_value); // should log "max_value" as a string
UPDATE: I need a testing function that should be able to log any variable name (passed as an argument) as a string, not just this one variable.
There is a solution that can help you. I grabbed this function from this stackoverflow answer, which is able to get the name of the function parameters:
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
then all you need to do now, is to use the name of your variable as a parameter of an anonymous function and pass all the function as argument of the getParamNames :
variablesNames = getParamNames(function (max_value, min_value) {});
This will return an array like this :
result => ["max_value", "min_value"];
Let's make it practical, first change the name of the getParamNames function to something easy and small like this :
function __ (func) {
// code here ...
}
second thing, instead of returning an array, just return the first element of the array, change this :
return result;
to this :
return result.shift();
now, you can get the name of your variable like this :
__(function( max_value ){});

PredicateBuilder where clause issue

I am using PredicateBuilder to generate where clause
var locationFilter = PredicateBuilder.True<dbCompanyLocation>();
locationFilter = locationFilter.And(s => s.IsPrimary == true && s.State == practiceState);
var companyPredicate = PredicateBuilder.True<dbCompany>();
companyPredicate = companyPredicate.And(c => c.dbCompanyLocations.Where(locationFilter));
I am getting following error, Any one can help for this or am i doing something wrong.
Instance argument: cannot convert from 'System.Data.Linq.EntitySet' to 'System.Linq.IQueryable'
The immediate problem seems to be that dbCompany.dbCompanyLocations is an EntitySet, which implements IEnumerable<T> rather than IQueryable<T>. This means its Where extension method expects a Func<dbCompanyLocation, bool>, however the locationFilter variable you are providing is an Expression<Func<dbCompanyLocation, bool>>.
You can create a Func<dbCompanyLocation, bool> from locationFilter by calling the Compile method.
Another problem however is that even if it did type check, c => c.dbCompanyLocations.Where(locationFilter) is not a predicate, since Where returns an IEnumerable<T> instead of a bool. You probably meant to use Any instead of Where i.e.
companyPredicate = companyPredicate.And(c => c.dbCompanyLocations.Any(locationFilter.Compile()));

Resources