Throwing NoSuchElementException for ranges - groovy

Lets say I have the following (ideone):
x = [1,2,3]
y = x.iterator();
println y.next();
println y.next();
println y.next();
println y.next();
This outputs:
1
2
3
Caught: java.util.NoSuchElementException
java.util.NoSuchElementException
at java_util_Iterator$next.call(Unknown Source)
at prog.run(prog.groovy:7)
As expected.
But lets change x = [1,2,3] to x = 1..3, so the code is the following (ideone):
x = 1..3
y = x.iterator();
println y.next();
println y.next();
println y.next();
println y.next();
Now we get the output:
1
2
3
null
And no exception is thrown. Why is this the case? It's really unexpected that [1,2,3] and 1..3 behave differently when iterating through them. It seems like such behaviour doesn't comply with iterator's contract.
Is there a way for me to fix this behaviour, and will such a fix break anything else?

Edit: Let me try to be clearer:
This is the correct usage of the Iterator class:
x = 1..3
y = x.iterator();
while(y.hasNext()) {
println y.next();
}
The NoSuchElement exception is an unchecked (AKA runtime) exception. The reason it's not checked is that it's something that should be avoidable completely without relying on the exception. This is different than, for example, IOExceptions, which are checked and far more likely to occur during normal use.
It's not explicitly stated one way or the other in the docs, but the only time I see the next() method throwing a NoSuchElementException when the Iterator is used correctly as above is if you have a modifiable collection in an unsynchronized, multi-threaded environment that has an item removed between the moment you call hasNext and access the item using next.
Because the Range class is unmodifiable, there is no chance, ever, of that situation rising.
You should not rely on unchecked Exceptions to determine the functionality or state of an item.
So, I don't really think the contract has been broken. The contract for using an iterator is to use hasNext before next, and the Range class's Iterator is not required to throw an exception just because it is being used incorrectly.

use :
While(y.hasNext()){
println y.next();
}

It's because IntRangeIterator returns null when it has gone off the end of the Range
As you can see in the source code for it here
I guess if you feel that this is incorrect behaviour, you should ask on the mailing lists, or post a bug to the Groovy JIRA, but as it's been that way for 6 years I would imagine it's going to stay that way (as it would be a breaking change)
As other people say, you should use a for or each mechanism to iterate the Iterator, or if that's not possible wrapping your calls to next() in a hasNext() check should catch all cases where you're off the end.

Related

What is the equivalent of 'pass' from Python?

I want to check if the result from a request is having any issue. I categorize it into two: i) server error, ii) something else that is not a success. The third category is, result actually being a success. However, in the third category, I don't want to do anything.
So, my desirable code is:
if res.status().is_server_error() {
panic!("server error!");
} else if !(res.status.is_success()){
panic!("Something else happened. Status: {:?}", res.status());
} else{
pass;
}
I am aware of other ways to achieve this result: using match, ifs instead of if else if. But I wanted to learn what is the corresponding keyword of pass, like we have in Python. My aim is: if result is successful, just move along, if not, there are two ways to handle that panic.
Behold!
if predicate {
do_things();
} else {
// pass
}
Or even better
if predicate {
do_things();
} // pass
Or as I’ve recently taken to calling it the implicit + pass system
if predicate {
do_things();
}
In all seriousness there is no pass and no need for a pass in rust. As for why it exists in python, check out this answer
Python needs pass because it uses indentation-based blocks, so it requires some syntax to "do nothing". For example, this would be a syntax error in a Python program:
# syntax error - function definition cannot be empty
def ignore(_doc):
# do nothing
count = process_docs(docs, ignore) # just count the docs
The ignore function has to contain a block, which in turn must contain at least one statement. We could insert a dummy statement like None, but Python provides pass which compiles to nothing and signals the intention (to do nothing) to the human reader.
This is not needed in Rust because Rust uses braces for blocks, so one can always create an empty block simply using {}:
// no error - empty blocks are fine
fn ignore(_doc: &Document) {
// do nothing
}
let count = process_docs(docs, ignore); // just count the docs
Of course, in both idiomatic Python and Rust, one would use a closure for something as simple as the above ignore function, but there are still situations where pass and empty blocks are genuinely useful.

Why are there different behaviors for the ways of addressing GString keys in maps?

While studying the Groovy (2.4.4) syntax in the official documentation, I came across the special behavior concerning maps with GStrings as identifiers. As described in the documentation, GStrings are a bad idea as (hash)map identifiers, because the hashcodes of a non-evaluated GString-object differs from a regular String-object with the same representation as the evaluated GString.
Example:
def key = "id"
def m = ["${key}": "value for ${key}"]
println "id".hashCode() // prints "3355"
println "${key}".hashCode() // prints "3392", different hashcode
assert m["id"] == null // evaluates true
However, my intuitive expectation was that using the actual GString identifier to address a key in the map will in fact deliver the value - but it does not.
def key = "id"
def m = ["${key}": "value for ${key}"]
assert m["${key}"] == null // evaluates also true, not expected
That made me curious. So I had several suggestions concerning this issue and did some experiments.
(pls keep in my mind that I am new to Groovy and I was just brainstorming on the fly - continue to Suggestion #4 if you do not want to read how I tried to examine the cause of the issue)
Suggestion #1. hashcode for GString objects works/is implemented somewhat non-deterministic for whatever reason and delivers different results depending on the context or the actual object.
That turned out to be nonsense quite fast:
println "${key}".hashCode() // prints "3392"
// do sth else
println "${key}".hashCode() // still "3392"
Suggestion #2. The actual key in the map or the map item does not have the expected representation or hashcode.
I took a closer look at the item in the map, the key, and its hashcode.
println m // prints "[id:value for id]", as expected
m.each {
it -> println key.hashCode()
} // prints "3355" - hashcode of the String "id"
So the hashcode of the key inside the map is different from the GString hashcode. HA! or not. Though it is nice to know, it is actually not relevant because I still do know the actual hashcodes in the map index. I just rehashed a key that has been transformed to a string after being put into the index. So what else?
Suggestion #3. The equals-method of a GString has an unknown or non- implemented behavior.
No matter whether two hashcodes are equal, they may not represent the same object in a map. That depends on the implementation of the equals method for the class of the key-object. If the equals-method is, for instance, not implemented, two objects are not equal even if the hashcode is identical and therefore the desired map key cannot be adressed properly. So I tried:
def a = "${key}"
def b = "${key}"
assert a.equals(b) // returns true (unfortunate but expected)
So two representations of the same GString are equal by default.
I skip some others ideas I tried and continue with the last thing I tried just before I was going to write this post.
Suggestion #4. The syntax of access matters.
That was a real killer of understanding. I knew before: There are syntactically different ways two access map values. Each way has its restrictions, but I thought the results stay the same. Well, this came up:
def key = "id"
def m = ["${key}": "value for ${key}"]
assert m["id"] == null // as before
assert m["${key}"] == null // as before
assert m.get("${key}") == null // assertion fails, value returned
So if I use the get-method of a map, I get the actual value in the way I expected it to in the first place.
What is the explanation for this map access behavior concerning GStrings? (or what kind of rookie mistake is hidden here?)
Thanks for your patience.
EDIT: I am afraid that my actual question is not clearly stated, so here is the case in short and concise:
When I have a map with a GString as a key like this
def m = ["${key}": "value for ${key}"]
why does this return the value
println m.get("${key}")
but that does not
println m["${key}"]
?
You can look at this matter with a very different approach. A map is supposed to have immutable keys (at least for hashcode and equals), because the map implementation depends on this. GString is mutable, thus not really suited for map keys in general. There is also the problem of calling String#equals(GString). GString is a Groovy class, so we can influence the equals method to equal to a String just fine. But String is very different. That means calling equals on a String with a GString will always be false in the Java world, even if hashcode() would behave the same for String and GString. And now imagine a map with String keys and you ask the map for a value with a GString. It would always return null. On the other hand a map with GString keys queried with a String could return the "proper" value. This means there will always be a disconnection.
And because of this problem GString#hashCode() is not equal to String#hashCode() on purpose.
It is in no way non-deterministic, but a GString hashcode can change, if the participating objects change their toString representation:
def map = [:]
def gstring = "$map"
def hashCodeOld = gstring.hashCode()
assert hashCodeOld == gstring.hashCode()
map.foo = "bar"
assert hashCodeOld != gstring.hashCode()
Here the toString representation of map will change for Groovy and GString, thus the GString will produce a different hashcode

Explanation of the statement below about Groovy closures.

I'm reading this: A closure looks a lot like a regular Java or Groovy code block, but actually it's not the same. The code within a regular code block (whether its a method block, static block, synchronized block, or just a block of code) is executed by the virtual machine as soon as it's encountered. With closures the statements within the curly brackets are not executed until the call() is made on the closure. In the previous example the closure is declared in line, but it's not executed at that time. It will only execute if the call() is explicitly made on the closure
And I'm thinking, how is this true, in Java if you have an instance method, the code is only executed when the method is called then how are they saying above that is executed by the VM as soon as it sees it ?
If I have a method func(){int a =5; return a+5;} this will be executed only when called is my understanding.
The description might be better taken with just synchronized block or regular scope braces. What it's attempting to show is that when the thread of execution hits a regular code block, it continues on executing the contents. With closure definitions, the code in the block is not immediately executed - it's used to define/instantiate a closure object (say, clos) which contains that logic, and which can be later executed via clos.call() (or just clos()).
example:
def x = 1
synchronized(this) {
x = 1000
}
println x //x == 1000
vs.
def x = 1
Closure clos = {
x = 1000
}
println x // x == 1
clos() // or clos.call()
println x // x == 1000
W/R/T method/static blocks: It's unclear to me if there is some nuanced way in which "encountered" and "executed" can be used in a JVM context that makes that part of the statement correct, but for practical purposes, it's at best misleading. Methods are still only executed when called, and not by virtue of their declarations being located in the apparent path of code execution, as the following can be run in groovyConsole to show:
def x = 1
void methodA() {
x = 1000
}
def b = {
x = x + 1
}
println x // x is still 1
Another analogy, which is not necessarily technically accurate, is to think about Closures as anonymous inner classes that have a single method (the body of the closure).
Doing either closure.call() or closure() (short-hand for call()), invokes that single method.
Closures have additional features, of course, but I think that this is a good way to think about the basics.

is it possible to break out of closure in groovy

is there a way to 'break' out of a groovy closure.
maybe something like this:
[1, 2, 3].each {
println(it)
if (it == 2)
break
}
I often forget that Groovy implements an "any" method.
[1, 2, 3].any
{
println it
return (it == 2)
}​
12/05/2013 Heavily Edited.
Answering the question that was asked.
Is it possible to break out of a Closure?
You would "break" out of a closure by issuing the return keyword. However that isn't helpful in the example that is given. The reason for this is that the closure (think of it as a method) is called by the each method for every item in the collection.
If you run this example you will see it will print 1 then 3.
[1, 2, 3].each {
if (it == 2) return
println(it)
}
Why break in the context of each doesn't make sense.
To understand why you cannot break out of the each method like you could break out of a for loop you need to understand a bit of what is actually happening. Here is a gross simplification what the each method on a collection does.
myEach([0,1,3])
void myEach(List things) {
for (i in things) {
myEachMethod(i)
}
}
void myEachMethod(Object it) { // this is your Closure
if(it == 2) return
println it
}
As you can see the closure is basically a method that can be passed around. Just as in java you cannot break from within method call or closure.
What to do instead of breaking from each.
In Groovy you are supposed to express your code using high level abstractions as such primitive looping is not idiomatic. For the example that you gave I would consider making use of findAll. For example:
[1,2,3].findAll { it < 2 }.each { println it }
I hope this helps you understand what is going on.
Answering the implied question.
Can you break out of the Collection.each iterations against your supplied closure?
You cannot break out of the each method without throwing and catching an exception as John Wagenleitner has said. Although I would argue that throwing and catching an exception in the name of flow control is a code smell and a fellow programmer might slap your hands.
You can throw an exception:
try {
[1, 2, 3].each {
println(it)
if (it == 2)
throw new Exception("return from closure")
}
} catch (Exception e) { }
Use could also use "findAll" or "grep" to filter out your list and then use "each".
[1, 2, 3].findAll{ it < 3 }.each{ println it }
Take a look at Best pattern for simulating continue in groovy closure for an extensive discussion.
Try to use any instead of each
def list = [1, 2, 3, 4, 5, -1, -2]
list.any { element ->
if (element > 3)
return true // break
println element
}
The result : 1, 2, 3
Just using special Closure
// declare and implement:
def eachWithBreak = { list, Closure c ->
boolean bBreak = false
list.each() { it ->
if (bBreak) return
bBreak = c(it)
}
}
def list = [1,2,3,4,5,6]
eachWithBreak list, { it ->
if (it > 3) return true // break 'eachWithBreak'
println it
return false // next it
}
There is an other solution. Although, that groovy stuff like each/find/any is quite cool: if it doesn't fit, don't use it. You can still use the plain old
for (def element : list)
Especially, if you want to leave the method, too. Now you are free to use continue/break/return as you like. The resulting code might not be cool, but it is easy and understandable.
This is in support of John Wagenleiter's answer. Tigerizzy's answer is plain wrong. It can easily be disproved practically by executing his first code sample, or theoretically by reading Groovy documentation. A return returns a value (or null without an argument) from the current iteration, but does not stop the iteration. In a closure it behaves rather like continue.
You won't be able to use inject without understanding this.
There is no way to 'break the loop' except by throwing an exception. Using exceptions for this purpose is considered smelly. So, just as Wagenleiter suggests, the best practice is to filter out the elements you want to iterate over before launching each or one of its cousins.
With rx-java you can transform an iterable in to an observable.
Then you can replace continue with a filter and break with takeWhile
Here is an example:
import rx.Observable
Observable.from(1..100000000000000000)
.filter { it % 2 != 1}
.takeWhile { it<10 }
.forEach {println it}

Groovy: what's the purpose of "def" in "def x = 0"?

In the following piece of code (taken from the Groovy Semantics Manual page), why prefix the assignment with the keyword def?
def x = 0
def y = 5
while ( y-- > 0 ) {
println "" + x + " " + y
x++
}
assert x == 5
The def keyword can be removed, and this snippet would produce the same results. So what's the effect of the keyword def ?
It's syntactic sugar for basic scripts. Omitting the "def" keyword puts the variable in the bindings for the current script and groovy treats it (mostly) like a globally scoped variable:
x = 1
assert x == 1
assert this.binding.getVariable("x") == 1
Using the def keyword instead does not put the variable in the scripts bindings:
def y = 2
assert y == 2
try {
this.binding.getVariable("y")
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
Prints: "error caught"
Using the def keyword in larger programs is important as it helps define the scope in which the variable can be found and can help preserve encapsulation.
If you define a method in your script, it won't have access to the variables that are created with "def" in the body of the main script as they aren't in scope:
x = 1
def y = 2
public bar() {
assert x == 1
try {
assert y == 2
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
}
bar()
prints "error caught"
The "y" variable isn't in scope inside the function. "x" is in scope as groovy will check the bindings of the current script for the variable. As I said earlier, this is simply syntactic sugar to make quick and dirty scripts quicker to type out (often one liners).
Good practice in larger scripts is to always use the "def" keyword so you don't run into strange scoping issues or interfere with variables you don't intend to.
Ted's answer is excellent for scripts; Ben's answer is standard for classes.
As Ben says, think of it as "Object" -- but it is much cooler in that it does not constrain you to the Object methods. This has neat implications with respect to imports.
e.g. In this snippet I have to import FileChannel
// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
import java.nio.channels.*
class Foo {
public void bar() {
FileChannel channel = new FileInputStream('Test.groovy').getChannel()
println channel.toString()
}
}
new Foo().bar()
e.g. But here I can just 'wing it' as long as everything is on the classpath
// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
class Foo {
public void bar() {
def channel = new FileInputStream('Test.groovy').getChannel()
println channel.toString()
}
}
new Foo().bar()
According to this page, def is a replacement for a type name and can simply be thought of as an alias for Object (i.e. signifying that you don't care about the type).
As far as this single script is concerned there is no practical difference.
However, variables defined using the keyword "def" are treated as local variables, that is, local to this one script. Variables without the "def" in front of them are stored in a so called binding upon first use. You can think of the binding as a general storage area for variables and closures that need to be available "between" scripts.
So, if you have two scripts and execute them with the same GroovyShell, the second script will be able to get all variables that were set in the first script without a "def".
The reason for "def" is to tell groovy that you intend to create a variable here. It's important because you don't ever want to create a variable by accident.
It's somewhat acceptable in scripts (Groovy scripts and groovysh allow you to do so), but in production code it's one of the biggest evils you can come across which is why you must define a variable with def in all actual groovy code (anything inside a class).
Here's an example of why it's bad. This will run (Without failing the assert) if you copy the following code and paste it into groovysh:
bill = 7
bi1l = bill + 3
assert bill == 7
This kind of problem can take a lot of time to find and fix--Even if it only bit you once in your life it would still cost more time than explicitly declaring the variables thousands of times throughout your career. It also becomes clear to the eye just where it's being declared, you don't have to guess.
In unimportant scripts/console input (like the groovy console) it's somewhat acceptable because the script's scope is limited. I think the only reason groovy allows you to do this in scripts is to support DSLs the way Ruby does (A bad trade-off if you ask me, but some people love the DSLs)
Actually, I don't think it would behave the same...
variables in Groovy still require declaration, just not TYPED declaration, as the right-hand side generally contains enough information for Groovy to type the variable.
When I try to use a variable that I haven't declared with def or a type, I get an error "No such property", since it assumes that I'm using a member of the class containing the code.

Resources