According to official Dart documentation, it is mentioned that:
Chaining method calls
a..b = true..c = 5;
Cascade used for chaining access to methods and other members.
Equivalent:
a.b = true; a.c = 5;
Can someone explain the meaning of the above lines?
Consider user as an instace of following class:
class User {
int age;
String firstName;
String lastName;
}
Now you can update data in user as following:
user.age = 5;
user.firstName = 'John';
user.lastName = 'Doe';
but if you use chaining access as described in the documentation.
Then it will look something like this:
user..age = 5
..firstName = 'John'
..lastName = 'Doe';
Note: sequence of assignment of the properties does not matter, but it might be of importance while calling functions or methods like this.
Just a simple & random example:
painter..computeLayout()
..initializePaint()
..render();
above is same as:
painter.computeLayout();
painter.initializePaint();
painter.render();
in the above example all of the methods were called on painter object/instance but the sequence here must be followed as without paint or layout the render will not work.
Cascades
To perform a sequence of operations on the same object, use cascades (..). We’ve all seen an expression like this:
myObject.someMethod()
It invokes someMethod() on myObject, and the result of the expression is the return value of someMethod().
Here’s the same expression with a cascade:
myObject..someMethod()
Although it still invokes someMethod() on myObject, the result of the expression isn’t the return value — it’s a reference to myObject! Using cascades, you can chain together operations that would otherwise require separate statements. For example, consider this code:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
With cascades, the code becomes much shorter, and you don’t need the button variable:
querySelector('#confirm')
..text = 'Confirm'
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
Related
I'm looking for the way how to get all statements from my model by its property and by a class of an object.
For example I have property :driverOf and individuals either of type Bus or Truck. Then I want to get all statements where the property is :driverOf and the object is instanceOf Bus. Thanks.
UPDATE 1
Actually I need the result to be a set of statements (resp. StmtIterator) because in my app I use statement objects already. I think the most clean solution would be to have subproperties of :driverOf property, something like :driverOfBus and :driverOfTruck. But it would make my app more complicated, so I would like to find out some simple workaround.
You could use sparql query. You have to replace labels with full namespaces.
String queryString =
"SELECT ?x WHERE { ?x driverOflabel ?y . {?y a Buslabel} UNION { ?y a Trucklabel} . }";
Query query = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(query, YOURMODEL);
try {
ResultSet results = qexec.execSelect();
while(results.hasNext()) {
QuerySolution soln = results.nextSolution();
System.out.println(soln.toString());
}
} finally {
qexec.close();
}
I hope i understood this correctly:
Say you have model m and namespace NAMESPACE
// Get the property and the subject
Property driverOf = m.getProperty(NAMESPACE + "driverOf");
Resource bus = m.getResource(NAMESPACE + "bus");
// Get all statements/triples of the form (****, driverOf, bus)
StmtIterator stmtIterator = m.listStatements(null, driverOf, bus);
while (stmtIterator.hasNext()){
Statement s = stmtIterator.nextStatement();
Resource busDriver = s.getObject();
// do something to the busdriver (only nice things, everybody likes busdrivers)
}
I am trying to use a HashMap of Lists of strings in Vala, but it seems the object lifecycle is biting me. Here is my current code:
public class MyClass : CodeVisitor {
GLib.HashTable<string, GLib.List<string>> generic_classes = new GLib.HashTable<string, GLib.List<string>> (str_hash, str_equal);
public override void visit_data_type(DataType d) {
string c = ...
string s = ...
if (! this.generic_classes.contains(c)) {
this.generic_classes.insert(c, new GLib.List<string>());
}
unowned GLib.List<string> l = this.generic_classes.lookup(c);
bool is_dup = false;
foreach(unowned string ss in l) {
if (s == ss) {
is_dup = true;
}
}
if ( ! is_dup) {
l.append(s);
}
}
Note that I am adding a string value into the list associated with a string key. If the list doesn't exist, I create it.
Lets say I run the code with the same values of c and s three times. Based some printf debugging, it seems that only one list is created, yet each time it is empty. I'd expect the list of have size 0, then 1, and then 1. Am I doing something wrong when it comes to the Vala memory management/reference counting?
GLib.List is the problem here. Most operations on GLib.List and GLib.SList return a modified pointer, but the value in the hash table isn't modified. It's a bit hard to explain why that is a problem, and why GLib works that way, without diving down into the C. You have a few choices here.
Use one of the containers in libgee which support multiple values with the same key, like Gee.MultiMap. If you're working on something in the Vala compiler (which I'm guessing you are, as you're subclassing CodeVisitor), this isn't an option because the internal copy of gee Vala ships with doesn't include MultiMap.
Replace the GLib.List instances in the hash table. Unfortunately this is likely going to mean copying the whole list every time, and even then getting the memory management right would be a bit tricky, so I would avoid it if I were you.
Use something other than GLib.List. This is the way I would go if I were you.
Edit: I recently added GLib.GenericSet to Vala as an alternative binding for GHashTable, so the best solution now would be to use GLib.HashTable<string, GLib.GenericSet<string>>, assuming you're okay with depending on vala >= 0.26.
If I were you, I would use GLib.HashTable<string, GLib.HashTable<unowned string, string>>:
private static int main (string[] args) {
GLib.HashTable<string, GLib.HashTable<unowned string, string>> generic_classes =
new GLib.HashTable<string, GLib.HashTable<unowned string, string>> (GLib.str_hash, GLib.str_equal);
for (int i = 0 ; i < 3 ; i++) {
string c = "foo";
string s = i.to_string ();
unowned GLib.HashTable<unowned string, string>? inner_set = generic_classes[c];
stdout.printf ("Inserting <%s, %s>, ", c, s);
if (inner_set == null) {
var v = new GLib.HashTable<unowned string, string> (GLib.str_hash, GLib.str_equal);
inner_set = v;
generic_classes.insert ((owned) c, (owned) v);
}
inner_set.insert (s, (owned) s);
stdout.printf ("container now holds:\n");
generic_classes.foreach ((k, v) => {
stdout.printf ("\t%s:\n", k);
v.foreach ((ik, iv) => {
stdout.printf ("\t\t%s\n", iv);
});
});
}
return 0;
}
It may seem hackish to have a hash table with the key and value having the same value, but this is actually a common pattern in C as well, and specifically supported by GLib's hash table implementation.
Moral of the story: don't use GLib.List or GLib.SList unless you really know what you're doing, and even then it's generally best to avoid them. TBH we probably would have marked them as deprecated in Vala long ago if it weren't for the fact that they're very common when working with C APIs.
Vala's new can be a little weird when used as a parameter. I would recommend assigning the new list to a temporary, adding it to the list, then letting it go out of scope.
I would also recommend using libgee. It has better handling of generics than GLib.List and GLib.HashTable.
This query produces an error No value given for one or more required parameters:
using (var conn = new OleDbConnection("Provider=..."))
{
conn.Open();
var result = conn.Query(
"select code, name from mytable where id = ? order by name",
new { id = 1 });
}
If I change the query string to: ... where id = #id ..., I will get an error: Must declare the scalar variable "#id".
How do I construct the query string and how do I pass the parameter?
The following should work:
var result = conn.Query(
"select code, name from mytable where id = ?id? order by name",
new { id = 1 });
Important: see newer answer
In the current build, the answer to that would be "no", for two reasons:
the code attempts to filter unused parameters - and is currently removing all of them because it can't find anything like #id, :id or ?id in the sql
the code for adding values from types uses an arbitrary (well, ok: alphabetical) order for the parameters (because reflection does not make any guarantees about the order of members), making positional anonymous arguments unstable
The good news is that both of these are fixable
we can make the filtering behaviour conditional
we can detect the category of types that has a constructor that matches all the property names, and use the constructor argument positions to determine the synthetic order of the properties - anonymous types fall into this category
Making those changes to my local clone, the following now passes:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?", new DynamicParameters(
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
) { RemoveUnused = false } ).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
Note that I'm currently using DynamicParameters here to avoid adding even more overloads to Query / Query<T> - because this would need to be added to a considerable number of methods. Adding it to DynamicParameters solves it in one place.
I'm open to feedback before I push this - does that look usable to you?
Edit: with the addition of a funky smellsLikeOleDb (no, not a joke), we can now do this even more directly:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?",
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
I've trialing use of Dapper within my software product which is using odbc connections (at the moment). However one day I intend to move away from odbc and use a different pattern for supporting different RDBMS products. However, my problem with solution implementation is 2 fold:
I want to write SQL code with parameters that conform to different back-ends, and so I want to be writing named parameters in my SQL now so that I don't have go back and re-do it later.
I don't want to rely on getting the order of my properties in line with my ?. This is bad. So my suggestion is to please add support for Named Parameters for odbc.
In the mean time I have hacked together a solution that allows me to do this with Dapper. Essentially I have a routine that replaces the named parameters with ? and also rebuilds the parameter object making sure the parameters are in the correct order.
However looking at the Dapper code, I can see that I've repeated some of what dapper is doing anyway, effectively it each parameter value is now visited once more than what would be necessary. This becomes more of an issue for bulk updates/inserts.
But at least it seems to work for me o.k...
I borrowed a bit of code from here to form part of my solution...
The ? for parameters was part of the solution for me, but it only works with integers, like ID. It still fails for strings because the parameter length isn't specifed.
OdbcException: ERROR [HY104] [Microsoft][ODBC Microsoft Access Driver]Invalid precision value
System.Data.Odbc. OdbcParameter.Bind(OdbcStatementHandle hstmt,
OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance)
System.Data.Odbc.OdbcParameterCollection.Bind(OdbcCommand command, CMDWrapper cmdWrapper, CNativeBuffer parameterBuffer)
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, SQL_API odbcApiMethod)
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader)
System.Data.Common.DbCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
Dapper.SqlMapper.QueryAsync(IDbConnection cnn, Type effectiveType, CommandDefinition command) in SqlMapper.Async.cs
WebAPI.DataAccess.CustomerRepository.GetByState(string state) in Repository.cs
var result = await conn.QueryAsync(sQuery, new { State = state });
WebAPI.Controllers.CustomerController.GetByState(string state) in CustomerController .cs
return await _customerRepo.GetByState(state);
For Dapper to pass string parameters to ODBC I had to specify the length.
var result = await conn.QueryAsync<Customer>(sQuery, new { State = new DbString { Value = state, IsFixedLength = true, Length = 4} });
In Rails, one could use:
returning Person.create do |p|
p.first_name = "Collin"
p.last_name = "VanDyck"
end
Avoiding having to do this:
person = Person.create
person.first_name = "Collin"
person.last_name = "VanDyck"
person
I think the former way is cleaner and less repetitive. I find myself creating this method in my Scala projects:
def returning[T](value: T)(fn: (T) => Unit) : T = {
fn(value)
value
}
I know that it is of somewhat limited utility due to the tendency of objects to be immutable, but for example working with Lift, using this method on Mapper classes works quite well.
Is there a Scala analog for "returning" that I'm not aware of? Or, is there a similar way to do this in Scala that's more idiomatic?
Your method looks fine, though I normally do this by adding a method for side-effects, which can include changing internal state (or also stuff like println):
class SideEffector[A](a: A) {
def effect(f: (A => Any)*) = { f.foreach(_(a)); a }
}
implicit def can_have_side_effects[A](a: A) = new SideEffector(a)
scala> Array(1,2,3).effect(_(2) = 5 , _(0) = -1)
res0: Array[Int] = Array(-1, 2, 5)
Edit: just in case it's not clear how this would be useful in the original example:
Person.create.effect(
_.first_name = "Collin",
_.last_name = "VanDyck"
)
Edit: changed the name of the method to "effect". I don't know why I didn't go that way before--side effect, not side effect for the naming.
Can't really improve much on what you've already written. As you quite correctly pointed out, idiomatic Scala tends to favour immutable objects, so this kind of thing is of limited use.
Plus, as a one-liner it's really not that painful to implement yourself if you need it!
def returning[T](value: T)(fn: T => Unit) : T = { fn(value); value }
I would do:
scala> case class Person(var first_name: String = "", var last_name: String = "")
defined class Person
scala> Person(first_name="Collin", last_name="VanDyck")
res1: Person = Person(Collin,VanDyck)
I don't understand why Vasil deleted his own answer, but I like it a lot (it was precisely what I was going to suggest):
val person = Person.create
locally { import person._
first_name = "Collin"
last_name = "VanDyck"
}
person
One of the features people have been asking for is the ability to auto-import something. If it were possible, then you could do this:
def returning[T](import value: T)(fn: => Unit) : T = { fn; value }
returning(Person.create) {
first_name = "Collin"
last_name = "VanDyck"
}
That is not possible at the moment, nor is it in Scala's roadmap. But some people do ask for something like that now and again.
It is possible to avoid repeating the variable name like so:
val person = Person.create
locally { import person._
first_name = "Collin"
last_name = "VanDyck"
}
Note that this only works for vals. Also, locally is a Predef method that helps to create blocks just to limit variable scope, without running afoul of Scala's semicolon inference. This keeps the import from getting in your way once you have finished initializing the person.
Another suggestion would be using the forward pipe operator from Scalaz.
val person = Person.create |> { p =>
p.firstName = "Collin"
p.lastName = "VanDyck"
p // or p.saveMe
}
The difference is that you would have to return the value yourself, if you want to assign it. If you do not need the return value (as in your initial example), things are easier:
Person.create |> { p =>
p.firstName = "Collin"
p.lastName = "VanDyck"
p.save
}
And there you go.
I was reluctant to really use it in my own code (even though I kind of favour this way of doing it – but it is only documented in scalaz and maybe hard to figure out for other people looking at the code), so I hope these examples do work.
You could of course define your own ‘forward and returning pipe’ using |>.
class ReturningPipe[A](value: A) {
import Scalaz._
def |>>[B](f: A => B):A = value.|>(a => { f(a); value})
}
implicit def returningPipe[A](value: A) = new ReturningPipe(value)
I'm browsing sample asp.net code in an MVC project and need a better understanding of the => operator. Plugging => into search engines is non-helpful.
thx
The => syntax creates lambda expressions, which are small functions.
For example, the line
Func<int, int> myFunc = i => 2 * i;
declares a variable of type Func<int, int> (a delegate that takes one integer and returns another one), and assigns it to a lambda expressions that takes a parameter called i (the compiler automatically figures out that i is an int) and returns 2 * i.
Yo can search it as lambda. See here http://msdn.microsoft.com/en-us/library/bb397687.aspx
The => operator, as has been mentioned, represents a lambda expression. This is short-hand for an anonymous delegate. Here is practical example:
If you want to filter all Person objects in a collection to return only Male people, the Where() extension method requires a Func delegate you could create a named delegate like this:
Func<Person, bool> isMale = delegate(Person peep) { return peep.Gender == "male"; };
var men = from p in peeps.Where(isMale)
select p;
Or you could use an anonymous delegate like this:
var women = from p in peeps.Where(delegate(Person peep) { return peep.Gender != "male"; })
select p;
The lambda allows you to declare the anonymous delegate using a short-hand, like this:
var women = from p in peeps.Where(x => x.Gender != "male")
select p;
Notice the correspondence between delegate(Person peep) and x, and between 'return peep.Gender != "male"and 'x.Gender != "male".