Consider below code
task circle {
doLast {
float r = Float.parseFloat(project.properties["radius"])
println (22/7)*(r ** 2)
}
}
task square {
doLast {
float s = Float.parseFloat(project.properties["side"])
println s*s
}
}
This give error as Cannot invoke method multiply() on null object
If I change the above code as below then it goes fine
task circle {
doLast {
float r = Float.parseFloat(project.properties["radius"])
println 22/7*(r ** 2)
}
}
task square {
doLast {
float s = Float.parseFloat(project.properties["side"])
println s*s
}
}
What could be the reason?
The problem here is the missing parens for the actual println, that
will lead to the following code being executed (println(22/7))*(r ** 2). The println is done first and its result (void) becomes
null. And then it throws the error you are seeing. Your "not-throwing"
example nudges the parser in the right direction.
Parens in groovy are "optional if unambiguous", which is quite a broad
term. Granted, that this got better with the new parrot-parser, you
will often see things like this blow up. Simple rule of thumb: just
don't leave out the parens for calling functions unless you are dealing
with a trivial term.
Related
OS windows. I would like to create a back-buffer before paint. I want to use boost::asio::thread_pool to increase speed. I need to stop back-buffer creating, if my "input data"(tasks) is updated.
I wrote Test_CreateAndCancel function to simplify test.
class Task
{
public:
virtual void operator()
{
std::cout << "Task started " << std::endl;
DoSomeWork();
std::cout << "Task in progress" << std::endl;
for (int i = 0; i < 15; ++i)
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
std::cout << "Task ended" << std::endl;
}
};
using TaskPtr = std::shared_ptr<Task>;
void Test_CreateAndCancel(std::vector<TaskPtr> &tasks)
{
//start back-buffer creating
boost::asio::thread_pool _thread_pool(4);
for (auto task : tasks)
{
boost::asio::post(thread_pool, [task] {
task->operator()();
});
}
// simulate cancel
thread_pool.stop(); // wait untill all threads are finished?
}
vector tasks has 4 items.
Result is: 4 "Task started" "Task in progress" "Task ended"
I am thinking to add custom IsCanceled() checkes in task::operator().
Is there are any other ways to make my tasks cancelable?
How can I implement cancel logic?
I will be grateful for any advices
Thanks
The easiest approach is to add a (probably atomic) variable "please_stop" to your Task and
query it inside the operator() regularly
set it from the outside (another task)
The basic problem is that you cannot cancel an operation that is running in a different task. You can only "ask it politely" to stop working.
boost::thread has an interrupt mechanism (see the link, #sehe posted above). This basically does not do anything different than what I suggested, except it's baked into boost::thread. There are certain "interruption points" that will query the "please stop" state and throw an exception, if it is set.
You have to catch the exception though, otherwise the thread itself will stop and you want only the operation to stop.
So you could do something like this:
class Task {
virtual void operator()()
{
try {
do_something();
boost::this_thread::sleep(boost::chrono::seconds(10000);
}
catch (boost::thread_interrupted&) { //
handle_please_stop_request();
}
}
};
// and later
task_thread.interrupt();
The problem with this approach is that you have to know the thread and you probably want to interrupt not the thread but the operation. Which is why the atomic approach has its charms.
BTW, your example has several problems. The task operation (operator()()) never stops at all. You are creating a task pool for every vector of tasks. I assume these are just artifacts of your example and your real world code is different.
One thing though. I haven't looked into asio::thread_pool yet, but I am missing the boost::asio::work object. Search stackoverflow on how to use the work object.
I was reading some Rust code and I came across this line
if let Some(path) = env::args().nth(1) {
Inside of this function
fn main() {
if let Some(path) = env::args().nth(1) {
// Try reading the file provided by the path.
let mut file = File::open(path).expect("Failed reading file.");
let mut content = String::new();
file.read_to_string(&mut content);
perform_conversion(content.as_str()).expect("Conversion failed.");
} else {
println!(
"provide a path to a .cue file to be converted into a MusicBrainz compatible tracklist."
)
}
}
The line seems to be assigning the env argument to the variable path but I can't work out what the Some() around it is doing.
I took a look at the documentation for Option and I understand how it works when used on the right hand side of = but on the left hand side I am a little confused.
Am I right in thinking this line is equivalent to
if let path = Some(env::args().nth(1)) {
From the reference :
An if let expression is semantically similar to an if expression but
in place of a condition expression it expects the keyword let followed
by a refutable pattern, an = and an expression. If the value of the
expression on the right hand side of the = matches the pattern, the
corresponding block will execute, otherwise flow proceeds to the
following else block if it exists. Like if expressions, if let
expressions have a value determined by the block that is evaluated.
In here the important part is refutability. What it means refutable pattern in here it can be in different forms. For example :
enum Test {
First(String, i32, usize),
Second(i32, usize),
Third(i32),
}
You can check the x's value for a value for 3 different pattern like :
fn main() {
let x = Test::Second(14, 55);
if let Test::First(a, b, c) = x {}
if let Test::Second(a, b) = x {} //This block will be executed
if let Test::Third(a) = x {}
}
This is called refutability. But consider your code like this:
enum Test {
Second(i32, usize),
}
fn main() {
let x = Test::Second(14, 55);
if let Test::Second(a, b) = x {}
}
This code will not compile because x's pattern is obvious, it has single pattern.
You can get more information from the reference of refutability.
Also you are not right thinking for this:
if let path = Some(env::args().nth(1)) {
Compiler will throw error like irrefutable if-let pattern because as the reference says: "keyword let followed by a refutable pattern". In here there is no refutable pattern after "let". Actually this code tries to create a variable named path which is an Option and this make no sense because there is no "If" needed,
Instead Rust expects from you to write like this:
let path = Some(env::args().nth(1)); // This will be seem like Some(Some(value))
The other answers go into a lot of detail, which might be more than you need to know.
Essentially, this:
if let Some(path) = env::args().nth(1) {
// Do something with path
} else {
// otherwise do something else
}
is identical to this:
match env::args().nth(1) {
Some(path) => { /* Do something with path */ }
_ => { /* otherwise do something else */ }
}
I am creating a doubly-linked-list of scripts (MSScripts) that are supposed to have their own run() implementation, and they call the next script (rscript) when they're ready . One of the scripts I'd like to create is just a delay. It looks like this:
class DelayScript : MSScript
{
var delay = 0.0
override func run() {
let delay = self.delay * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
let weakSelf = self
dispatch_after(time, dispatch_get_main_queue()) {
weakSelf.rscript?.run()
Void.self
}
}
init(delay: Double) {
super.init()
self.delay = delay
}
}
Where rscript is the next script to run. The problem is that if I remove the last line of the dispatch_after, it doesn't compile, and that's because of the changed return type of run() from optional chaining. I randomly decided to insert Void.self and it fixed the problem, but I have no idea why.
What is this Void.self, and is it the right solution?
Optional chaining wraps whatever the result of the right side is inside an optional. So if run() returned T, then x?.run() returns T?. Since run() returns Void (a.k.a. ()), that means the whole optional chaining expression has type Void? (or ()?).
When a closure has only one line, the contents of that line is implicitly returned. So if you only have that one line, it is as if you wrote return weakSelf.rscript?.run(). So you are returning type Void?, but dispatch_async needs a function that returns Void. So they don't match.
One solution is to add another line that explicitly returns nothing:
dispatch_after(time, dispatch_get_main_queue()) {
weakSelf.rscript?.run()
return
}
Edit: OK, here's a much much simpler example illustrating my problem. why is only the first task ever put onto the queue?
import std.stdio;
import std.parallelism;
void simpleWorker(uint depth, uint maxDepth, TaskPool pool){
writeln("Depth is: ",depth);
if (++depth < maxDepth){
pool.put( task!simpleWorker(depth,maxDepth,pool));
}
}
void main(){
auto pool = new TaskPool();
pool.put(task!simpleWorker(0,5,pool));
pool.finish(true);
writeln("Done");
}
Original:
I need to traverse this DAG. When I visit a node I clean it. I can't clean a node until all of its parents are clean.
The way I'm attempting is to have the worker thread's current node check all of its children to see which ones can be processed. Any that can be processed are added to the TaskPool.
My problem is I can't figure out how to add new tasks to the TaskPool and get them processed. This just cleans the first node in the DAG, and then exits, leaving everything else dirty.
void cleanNode(Node node, TaskPool pool){
node.doProcess();
foreach (client; node.clients){
if (client.canProcess()){
pool.put(task!cleanNode(client, pool));
}
}
}
void main(){
auto dag = mkTestDag(5);
auto pool = new TaskPool();
pool.put( task!cleanNode(dag[0], pool));
pool.finish(true);
writeln("\n\nOutput:");
foreach (d;dag){
writeln(d);
writeln(d.dirty ? "dirty" : "clean","\n");
}
}
The full code is here: http://pastebin.com/LLfMyKVp
It is because an Error is being thrown from the put inside simpleWorker.
This version shows the error:
import std.stdio;
import std.parallelism;
void simpleWorker(uint depth, uint maxDepth, TaskPool pool){
writeln("Depth is: ",depth);
if (++depth < maxDepth){
try {
pool.put( task!simpleWorker(depth,maxDepth,pool));
} catch (Error e) {
writeln("Fail: ", e.msg);
}
}
}
void main(){
auto pool = new TaskPool();
pool.put(task!simpleWorker(0,5,pool));
pool.finish(true);
writeln("Done");
}
And the output:
Depth is: 0
Fail: Cannot submit a new task to a pool after calling finish() or stop().
Done
Hopefully someone else can explain the correct way to use TaskPool.
Edit
Got it working by telling the tasks to run like this:
import std.stdio;
import std.parallelism;
void simpleWorker(uint depth, uint maxDepth, TaskPool pool){
writeln("Depth is: ",depth);
if (++depth < maxDepth){
try
{
auto subWorker = task!simpleWorker(depth,maxDepth, pool);
pool.put(subWorker);
subWorker.yieldForce();
} catch (Error t) {
writeln("Fail: (", typeof(t).stringof, ") ", t.msg);
}
}
}
void main(){
auto pool = new TaskPool();
auto worker = task!simpleWorker(0,5, pool);
pool.put(worker);
worker.yieldForce();
pool.finish(true);
writeln("Done");
}
Output:
Depth is: 0
Depth is: 1
Depth is: 2
Depth is: 3
Depth is: 4
Done
You have such behaviour because your canProcess() returns false for all nodes except the root node. Since cleanNodeSimple() calls canProcess() to check whether to put new task to the pool, it never does that I believe...
Check the output of this (modified) program: http://dpaste.dzfl.pl/ea0c393a .
EDIT:
Furthermore, after some analysis, the loop is executed only once as well, so nothing is added to the task pool. :)
Code is on DPaste, check it out. Here is the most interesting part that may help you solve the problem:
// Dejan: will be called only once!
// Because canProcess() returns false for all children.
void cleanNodeSimple(Node node, TaskPool pool){
node.doProcess();
writeln("cleanNodeSimple() called for node `", node, "`");
foreach (cli; node.clients){
writeln("I am ", cli, " and I am executed only once, because I am only RootNode's client.");
if (cli.canProcess()) {
writeln("I will be executed only once because because ", cli, " has ", cli.clients.length, " clients.");
writeln("And its master #1 is ", cli.clients[0].masters[0].dirty ? "dirty" : "clean");
pool.put( task!cleanNodeSimple(cli, pool) );
}
}
}
to iterate in a parallel fashion you can use parallel:
foreach (client; pool.parallel(node.clients,1)){
if (client.canProcess()){
cleanNode(client, pool);//<- EDIT: no need to make a task here
}
}
this will block until all clients have been iterated over (letting the current thread do some work as well)
to start you need to force the first task in main() instead of calling finish on the pool
The most egregiously redundant code construct I often see involves using the code sequence
if (condition)
return true;
else
return false;
instead of simply writing
return (condition);
I've seen this beginner error in all sorts of languages: from Pascal and C to PHP and Java. What other such constructs would you flag in a code review?
if (foo == true)
{
do stuff
}
I keep telling the developer that does that that it should be
if ((foo == true) == true)
{
do stuff
}
but he hasn't gotten the hint yet.
if (condition == true)
{
...
}
instead of
if (condition)
{
...
}
Edit:
or even worse and turning around the conditional test:
if (condition == false)
{
...
}
which is easily read as
if (condition) then ...
Using comments instead of source control:
-Commenting out or renaming functions instead of deleting them and trusting that source control can get them back for you if needed.
-Adding comments like "RWF Change" instead of just making the change and letting source control assign the blame.
Somewhere I’ve spotted this thing, which I find to be the pinnacle of boolean redundancy:
return (test == 1)? ((test == 0) ? 0 : 1) : ((test == 0) ? 0 : 1);
:-)
Redundant code is not in itself an error. But if you're really trying to save every character
return (condition);
is redundant too. You can write:
return condition;
Declaring separately from assignment in languages other than C:
int foo;
foo = GetFoo();
Returning uselessly at the end:
// stuff
return;
}
I once had a guy who repeatedly did this:
bool a;
bool b;
...
if (a == true)
b = true;
else
b = false;
void myfunction() {
if(condition) {
// Do some stuff
if(othercond) {
// Do more stuff
}
}
}
instead of
void myfunction() {
if(!condition)
return;
// Do some stuff
if(!othercond)
return;
// Do more stuff
}
Using .tostring on a string
Putting an exit statement as first statement in a function to disable the execution of that function, instead of one of the following options:
Completely removing the function
Commenting the function body
Keeping the function but deleting all the code
Using the exit as first statement makes it very hard to spot, you can easily read over it.
Fear of null (this also can lead to serious problems):
if (name != null)
person.Name = name;
Redundant if's (not using else):
if (!IsPostback)
{
// do something
}
if (IsPostback)
{
// do something else
}
Redundant checks (Split never returns null):
string[] words = sentence.Split(' ');
if (words != null)
More on checks (the second check is redundant if you are going to loop)
if (myArray != null && myArray.Length > 0)
foreach (string s in myArray)
And my favorite for ASP.NET: Scattered DataBinds all over the code in order to make the page render.
Copy paste redundancy:
if (x > 0)
{
// a lot of code to calculate z
y = x + z;
}
else
{
// a lot of code to calculate z
y = x - z;
}
instead of
if (x > 0)
y = x + CalcZ(x);
else
y = x - CalcZ(x);
or even better (or more obfuscated)
y = x + (x > 0 ? 1 : -1) * CalcZ(x)
Allocating elements on the heap instead of the stack.
{
char buff = malloc(1024);
/* ... */
free(buff);
}
instead of
{
char buff[1024];
/* ... */
}
or
{
struct foo *x = (struct foo *)malloc(sizeof(struct foo));
x->a = ...;
bar(x);
free(x);
}
instead of
{
struct foo x;
x.a = ...;
bar(&x);
}
The most common redundant code construct I see is code that is never called from anywhere in the program.
The other is design patterns used where there is no point in using them. For example, writing "new BobFactory().createBob()" everywhere, instead of just writing "new Bob()".
Deleting unused and unnecessary code can massively improve the quality of the system and the team's ability to maintain it. The benefits are often startling to teams who have never considered deleting unnecessary code from their system. I once performed a code review by sitting with a team and deleting over half the code in their project without changing the functionality of their system. I thought they'd be offended but they frequently asked me back for design advice and feedback after that.
I often run into the following:
function foo() {
if ( something ) {
return;
} else {
do_something();
}
}
But it doesn't help telling them that the else is useless here. It has to be either
function foo() {
if ( something ) {
return;
}
do_something();
}
or - depending on the length of checks that are done before do_something():
function foo() {
if ( !something ) {
do_something();
}
}
From nightmarish code reviews.....
char s[100];
followed by
memset(s,0,100);
followed by
s[strlen(s)] = 0;
with lots of nasty
if (strcmp(s, "1") == 0)
littered about the code.
Using an array when you want set behavior. You need to check everything to make sure its not in the array before you insert it, which makes your code longer and slower.
Redundant .ToString() invocations:
const int foo = 5;
Console.WriteLine("Number of Items: " + foo.ToString());
Unnecessary string formatting:
const int foo = 5;
Console.WriteLine("Number of Items: {0}", foo);