I have a method that takes an System.Action, this is what I'm trying to feed it:
Function() Me._existingImports = Me.GetImportedAds()
The thing is that it complains about the = sign since it thinks I'm trying to do a comparison, which I'm not. I want to assign the Me._existingImports the value of Me.GetImportedAds(), but VB.NET complains about DataTable not having a = operator.
How can I force it to use the assignment operator instead of the equality operator?
In C# this works perfectly fine:
() => this.existingImports = this.GetImportedAds()
For now the solution will be to use a standalone method, but that's way more code than needed.
When using Function(), you really define an anonymous function which means you map values to values.
Therefore Function() strictly needs an expression (like x or 42 ...) as the body, which an assignment is not! (Assignments don't evaluate to values like in C-style languages in VB)
Thus what you need is not a Function() but a Sub(), which contains statements (actions) rather than values.
Sub() Me._existingImports = Me.GetImportedAds()
C# doesn't distinguish here, the (much nicer) ... => ... syntax covers it all.
Related
I'm new to Lua and trying to understand the concept of OOP in Lua. To do so, I've tried creating an object and creating methods and "private variables". My issue is when I try to use "setters" or "getters", it's indicating that my tables are returning NIL which means I'm either having a scoping issue or something else I can't figure out.
The kicker is I'm using an example from an online Lua coding tutorial, and when I run the tutorial it works flawlessly. However, when I run mine, I get NIL or nothing outputs whenever I try to "get" or return a value from one of the member functions.
I'm using a couple of different environments:
ZeroBrain
Sublime Text
Lua for Windows
Do you know why my code is not returning populated tables?
newPlayer = function(n, h, a, r)
player = {}
n = n or ""
h = h or 100
a = a or 100
r = r or 0
function player:getPlayerName()
return n
end
function player:getPlayerHealth()
return h
end
function player:getPlayerArmor()
return a
end
function player:getPlayerRank()
return r
end
function player:setPlayerName(arg)
n = arg
end
function player:setPlayerHealth(arg)
h = arg
end
function player:setPlayerArmor(arg)
a = arg
end
function player:setPlayerRank(arg)
r = arg
end
function player:connect(arg)
print(string.format(" %s joined" , arg))
end
return player
end
player1 = newPlayer("John", 100, 100, 1000)
player1.getPlayerName()
Your code does not contain "populated tables" to return.
Your newPlayer function does create a table, and it does return it. It creates a number of functions within that table. But that's all newPlayer does: creates a table and puts some functions in it.
The data accessed by those functions is not part of the table. n, h, a, and r (BTW, please use better variable names) are all local variables. Your inner functions will access the specific stack containing those variables, but the variables themselves will not be magically associated with the table.
Your principle problem is almost certainly with the setters. And it comes from a combination of this:
function player:setPlayerName(arg)
with this:
player1.getPlayerName()
When you create a function using a : character between a table name and the function's name, you are using syntactic sugar for a function which implicitly takes as its first argument a value called self. As the name suggests, this is supposed to represent the object which this function is being called upon. So your function creation code is equivalent to:
function player.setPlayerName(self, arg)
Since you create all of your functions with :, all of your functions take at least one parameter.
The : syntax can also be used when calling such functions. If you did player1:getPlayerName(), this would cause the table you accessed to find the getPlayerName function to be used as the first argument in the function call. So that line would be equivalent to player1.getPlayerName(player1).
Obviously, these two syntaxes are mirrors of one another: functions created with : take a parameter that is expected to refer to the table it is being called on, and functions called with : will be given the table which was accessed to get that function.
But... your code didn't stick to the symmetry. You created the functions with :, but you call them with .
Now, you get functions are able to get away with this because... well, none of your values are actually part of the table. So your get functions just return the local value that they adopted from their creating context.
The set functions pose a problem. See, they take a parameter. But because the function was declared with :, they really take two parameters, the first being the implicit self.
Now, : syntax is just syntactic sugar; it's just a convenient way to do what you could have done yourself. So it is in theory OK to call a function with . even if you created it with :. But if you do so, you must pass the table as the first parameter. Though your code doesn't show it, I strongly suspect you didn't do that.
If you called player1.setPlayerName("foo"), what will happen is that the implicit self parameter will get the value "foo", and the arg parameter will be nil. And you will assign that nil value to the n local variable. So subsequent calls to player1.getPlayerName() will return nil.
Basically, what's going on here is that you're combining two different ways of creating objects in Lua. You stored your private data in a way that external code cannot access (ie: local upvalues), but that data is now no longer part of the table itself. Which means that, although you dutifully create those functions with : syntax to indicate that they take a self table, they never actually use that table. And because they never use the table, it's a lot harder to figure out what's going wrong.
Basically, the key here is to be symmetrical. If you create a function with :, then you should either call it with : or make sure to pass it the object table as the first parameter.
Broadly speaking, the standard way to create private members is by convention, not by forbidding it. That is, you agree not to mess with any members of a table other than those with certain names. Python convention is to pretend that names starting with _ don't exist, and Lua programs sometimes use that.
Upvalues are an interesting solution for private variables, but they do come with problems. If you want to invent a member variable, you have to do it in a centralized place rather than wherever you might need one. Even if the variable is optional, you have to create a named local at the top of the function.
TLDR of Nicol's answer, see my answer to another question:
function player:setPlayerArmor(arg)
a = arg
end
The : syntax is syntactic sugar. It creates an implicit 'self' argument when declared, and when used. If you declare it one way and use it another, the arguments won't be what you're expecting. Say your player has 100 health. Look at this result:
player1.setPlayerHealth(55, 66)
print(player1.getPlayerHealth())
-- will display '66', not '55' because `:` declares implicit 'self' argument
This displays 66 because the setPlayerHealth function has an implicit 'self' parameter because it was declared with :. If you instead called it
with the ::
player1:setPlayerHealth(55, 66)
print(player1:getPlayerHealth())
-- will display '55' because `:` passes player1 as self
function player:setHealth1(arg)
-- implicit 'self' argument refers to player1 when called on player1
end
-- is the same as
function player.setHealth2(self, arg)
-- with `.` notation, you need to add the 'self' argument explicitly
end
player1.setHealth1(31) -- self argument will be 31 and arg will be nil
player1.setHealth2(32) -- self argument will be 32 and arg will be nil
player1:setHealth1(33) -- self argument will be player1 and arg will be 33
player1:setHealth2(34) -- self argument will be player1 and arg will be 34
I keep reading (for example in the Closure Compiler and other compilers) that inlining of functions isn't always safe. Could you please provide an example when inlining of functions shouldn't be done?
In many languages, inlining a function will have no observable semantic effects, although it is likely to affect the compiled size and execution time of the program. However, that is not true in languages in which the call stack and/or local variable bindings are visible.
As a simple example, in Javscript the local variable arguments always refers to an array-like object containing the arguments to the current function call. Clearly, if the function in which it occurred were inlined, its semantics would change. An inliner would have to either refuse to inline a function whose body references arguments or it would have to modify the code in a way which preserved the semantics, possibly by creating another local variable with a different name and substituting the reference.
Another example would be the (non-recommended) use of eval. Name lookup in the string passed to eval is done within the scope of the function which calls eval. For example:
inner = function(s) { var x = 4; return eval(s); }
outer = function(s) { var x = 3; return inner(s); }
outer("x+1")
Here the value returned by outer is 5. If inner were inlined, which would require renaming its local variable x to avoid name conflict, the value returned would be 4. (If both inner and outer were inlined, the value would probably be something else again.)
In general, it's going to be very difficult to inline a function which calls eval because there is no easy way to know the contents of the argument to eval.
I'm learning D and have seen a lot of code like this:
ushort x = to!ushort(args[1]);
I assume this casts args[1] to ushort, but what's the difference between this and cast(ushort)?
EDIT: And what other uses does the exclamation mark operator have?
In D,
to!ushort(args[1])
is shorthand for the template instantiation
to!(ushort)(args[1])
and is similar to
to<ushort>(args[1])
in languages like C++/Java/C#.
The exclamation point is to note the fact that it's not a regular argument, but a template argument.
The notation does not use angle brackets because those are ridiculously difficult to parse correctly for a compiler (they make the grammar very context-sensitive), which makes it that much more difficult to implement a correct compiler. See here for more info.
The only other use I know about is just the unary 'not' operation (e.g. false == !true)... I can't think of any other uses at the moment.
Regarding the cast:
cast(ushort) is an unchecked cast, so it won't throw an exception if the value is out of range.
to!ushort() is a checked cast, so it throws an exception if the value is out of range.
The exclamation mark here is not an operator, it is just a token part of the explicit template instantiation syntax (described in detail here).
std.conv.to (docs) is a function template for converting between arbitrary types. It is implemented entirely in the library and has no special support in the language. It has a broader and different scope compared to the cast operator.
The to template takes two type parameters; a "to" type and a "from" type, in that order. In your example, the template is explicitly instantiated with the single type argument ushort for the "to" parameter, and a second type argument string (assuming args comes from the first parameter to main) is automatically inferred from the regular function argument passed to the function (args[1]) as the "from" parameter.
The resulting function takes a string parameter and returns a ushort parsed from that string, or throws an exception if it failed. The cast operator will not attempt this kind of high-level conversion.
Note that if there is more than one explicit template parameter, or that parameter has more than one token in it (ushort is a single keyword token), you must wrap the template parameter list in parentheses:
ushort result;
result = to!(typeof(result))(args[1]);
In this example, typeof, (, result and ) are four separate tokens and the parentheses are thus required.
To answer your last question, the ! token is also used for the unary not operator, unrelated to template instantiations:
bool yes = true;
bool no = !yes; // 'no' is false
You already got two excellent answers by jA_cOp and Merhdad. I just want answer directly to the OP question (what's the difference between this and cast(ushort)?) - The difference is that cast(ushort)args[1] will not work (you cannot cast from a string to an uint just like that), while the to!(type)(param) template knows what to do with the string and how to convert it to the primitive type.
In Perl (and other languages) a conditional ternary operator can be expressed like this:
my $foo = $bar == $buz ? $cat : $dog;
Is there a similar operator in VB.NET?
Depends upon the version. The If operator in VB.NET 2008 is a ternary operator (as well as a null coalescence operator). This was just introduced, prior to 2008 this was not available. Here's some more info: Visual Basic If announcement
Example:
Dim foo as String = If(bar = buz, cat, dog)
[EDIT]
Prior to 2008 it was IIf, which worked almost identically to the If operator described Above.
Example:
Dim foo as String = IIf(bar = buz, cat, dog)
iif has always been available in VB, even in VB6.
Dim foo as String = iif(bar = buz, cat, dog)
It is not a true operator, as such, but a function in the Microsoft.VisualBasic namespace.
If() is the closest equivalent, but beware of implicit conversions going on if you have set Option Strict off.
For example, if you're not careful you may be tempted to try something like:
Dim foo As Integer? = If(someTrueExpression, Nothing, 2)
Will give foo a value of 0!
I think the ? operator equivalent in C# would instead fail compilation.
Just for the record, here is the difference between If and IIf:
IIf(condition, true-part, false-part):
This is the old VB6/VBA Function
The function always returns an Object type, so if you want to use the methods or properties of the chosen object, you have to re-cast it with DirectCast or CType or the Convert.* Functions to its original type
Because of this, if true-part and false-part are of different types there is no matter, the result is just an object anyway
If(condition, true-part, false-part):
This is the new VB.NET Function
The result type is the type of the chosen part, true-part or false-part
This doesn't work, if Strict Mode is switched on and the two parts are of different types. In Strict Mode they have to be of the same type, otherwise you will get an Exception
If you really need to have two parts of different types, switch off Strict Mode (or use IIf)
I didn't try so far if Strict Mode allows objects of different type but inherited from the same base or implementing the same Interface. The Microsoft documentation isn't quite helpful about this issue. Maybe somebody here knows it.
If(<expression>, <expressionIfNothing>)
If <expression> evaluates to a reference or Nullable value that is not Nothing, the function returns that value. Otherwise, it calculates and returns <expressionIfNothing> (Intellisense)
This is useful for checking that a particular value exists, and if not replacing it.
Example:
If(cat, dog)
Here, if the cat is not null, it will return cat. If it is null, it will return dog. Most of the time you will be using a ternary operator for this scenario. However, if you do not want to return the value you are testing you will have to use this instead:
If(condition, cat(true), dog(false))
Consider the following line of code:
private void DoThis() {
int i = 5;
var repo = new ReportsRepository<RptCriteriaHint>();
// This does NOT work
var query1 = repo.Find(x => x.CriteriaTypeID == i).ToList<RptCriteriaHint>();
// This DOES work
var query1 = repo.Find(x => x.CriteriaTypeID == 5).ToList<RptCriteriaHint>();
}
So when I hardwire an actual number into the lambda function, it works fine. When I use a captured variable into the expression it comes back with the following error:
No mapping exists from object type
ReportBuilder.Reporter+<>c__DisplayClass0
to a known managed provider native
type.
Why? How can I fix it?
Technically, the correct way to fix this is for the framework that is accepting the expression tree from your lambda to evaluate the i reference; in other words, it's a LINQ framework limitation for some specific framework. What it is currently trying to do is interpret the i as a member access on some type known to it (the provider) from the database. Because of the way lambda variable capture works, the i local variable is actually a field on a hidden class, the one with the funny name, that the provider doesn't recognize.
So, it's a framework problem.
If you really must get by, you could construct the expression manually, like this:
ParameterExpression x = Expression.Parameter(typeof(RptCriteriaHint), "x");
var query = repo.Find(
Expression.Lambda<Func<RptCriteriaHint,bool>>(
Expression.Equal(
Expression.MakeMemberAccess(
x,
typeof(RptCriteriaHint).GetProperty("CriteriaTypeID")),
Expression.Constant(i)),
x)).ToList();
... but that's just masochism.
Your comment on this entry prompts me to explain further.
Lambdas are convertible into one of two types: a delegate with the correct signature, or an Expression<TDelegate> of the correct signature. LINQ to external databases (as opposed to any kind of in-memory query) works using the second kind of conversion.
The compiler converts lambda expressions into expression trees, roughly speaking, by:
The syntax tree is parsed by the compiler - this happens for all code.
The syntax tree is rewritten after taking into account variable capture. Capturing variables is just like in a normal delegate or lambda - so display classes get created, and captured locals get moved into them (this is the same behaviour as variable capture in C# 2.0 anonymous delegates).
The new syntax tree is converted into a series of calls to the Expression class so that, at runtime, an object tree is created that faithfully represents the parsed text.
LINQ to external data sources is supposed to take this expression tree and interpret it for its semantic content, and interpret symbolic expressions inside the tree as either referring to things specific to its context (e.g. columns in the DB), or immediate values to convert. Usually, System.Reflection is used to look for framework-specific attributes to guide this conversion.
However, it looks like SubSonic is not properly treating symbolic references that it cannot find domain-specific correspondences for; rather than evaluating the symbolic references, it's just punting. Thus, it's a SubSonic problem.