How to check for null in a single statement in scala? - scala

In my scala code:
QueueManager.add(getObject)
where getObject is a method that returns an object of type QueueObject.
def getObject : QueuObject = {
val response = //some response
return response
}
Is there a way I can check for the response being null, while adding the QueueObject? I know I can do this:
if (getObject != null)
QueueManager.add(getObject)
But I do not wish to add a level of indentation. Is there an operator that does that inline?
Thanks.

Try to avoid using null in Scala. It's really there only for interoperability with Java. In Scala, use Option for things that might be empty. If you're calling a Java API method that might return null, wrap it in an Option immediately.
def getObject : Option[QueueObject] = {
// Wrap the Java result in an Option (this will become a Some or a None)
Option(someJavaObject.getResponse)
}
Note: You don't need to put it in a val or use an explicit
return statement in Scala; the result will be the value of
the last expression in the block (in fact, since there's only one statement, you don't even need a block).
def getObject : Option[QueueObject] = Option(someJavaObject.getResponse)
Besides what the others have already shown (for example calling foreach on the Option, which might be slightly confusing), you could also call map on it (and ignore the result of the map operation if you don't need it):
getObject map QueueManager.add
This will do nothing if the Option is a None, and call QueueManager.add if it is a Some.
I find using a regular if however clearer and simpler than using any of these "tricks" just to avoid an indentation level. You could also just write it on one line:
if (getObject.isDefined) QueueManager.add(getObject.get)
or, if you want to deal with null instead of using Option:
if (getObject != null) QueueManager.add(getObject)
edit - Ben is right, be careful to not call getObject more than once if it has side-effects; better write it like this:
val result = getObject
if (result.isDefined) QueueManager.add(result.get)
or:
val result = getObject
if (result != null) QueueManager.add(result)

Option(getObject) foreach (QueueManager add)

If it instead returned Option[QueueObject] you could use a construct like getObject.foreach { QueueManager.add }. You can wrap it right inline with Option(getObject).foreach ... because Option[QueueObject](null) is None.

Although I'm sure #Ben Jackson's asnwer with Option(getObject).foreach is the preferred way of doing it, I like to use an AnyRef pimp that allows me to write:
getObject ifNotNull ( QueueManager.add(_) )
I find it reads better.
And, in a more general way, I sometimes write
val returnVal = getObject ifNotNull { obj =>
returnSomethingFrom(obj)
} otherwise {
returnSomethingElse
}
... replacing ifNotNull with ifSome if I'm dealing with an Option. I find it clearer than first wrapping in an option and then pattern-matching it.
(For the implementation, see Implementing ifTrue, ifFalse, ifSome, ifNone, etc. in Scala to avoid if(...) and simple pattern matching and the Otherwise0/Otherwise1 classes.)

Related

Working with Scala Option

I have been changing a lot of my Scala code recently to avoid instantiating variables with null and instead using Option. For example, I previously had:
var cxn: RepositoryConnection = null
cxn = repo.getConnection()
//do something with the connection, then close it
cxn.close()
Now, my code looks more like this.
var cxn = None : Option[RepositoryConnection]
cxn = Some(repo.getConnection())
//do something with the connection, then close it
Now the problem I have is when I want to call a method associated with the RepositoryConnection type. I try:
cxn.close()
and see this error:
value close is not a member of Option[org.openrdf.repository.RepositoryConnection]
Now, when I was using null, this operation worked just fine, because cxn was a RepositoryConnection object, not an Option[RepositoryConnection]. Is there an easy way to call the close() method now that I am using Option?
You have a few options. (Sorry about the pun.) The most straight forward is probably...
cxn.map(_.close())
But perhaps you need to do something else if cxn is None. Then you could do something like...
cxn.fold(logger.reportStatus())(_.close())
Since your variable is Option[Something], you can not call instanceOfSomethingOpt.methodOfInstance()
Instead do instanceOfSomethingOpt.map(realInstance => realInstance.methodOfInstance())
In your case, it'd be
cxn.map(realConnection => realConnection.close())
//or to make it shorter
cxn.map(_.close())
You should really give a look at Option api.
cxn.map(_.close())
is one way, in case close() returns something you might beed.
cxn.foreach(_.close())
is another way, if close() is not doing much (side-effect).
val cxn = Some(repo.getConnection())
for (c <- cxn) yield {
//do something with the connection
c.close()
}
Alternatively you can wrap the getConnection with Either or Try depending on how you want to handle errors see http://blog.xebia.com/try-option-or-either/

Capture a return value for logging and then return the value in Scala

What is the most 'scala-ic' way to capture a value (possibly one that is not idempotent) for logging and returning the same value.
I can think of 'return' statement the only way to do it, but apparently using 'return' should be avoided in scala .
Use case:
def myfunc(argument) : ReturnType{
val response:ReturnType = dependency()
// dependency() is not idemptotent
// so calling more than once will have side-effects
logger.debug(response.member1 , response.member2)
return response
}
Is there a way to achieve this without using a 'return' keyword.
I am a newbie to scala so some (or most) of what I said could be wrong, and would be happy to be corrected.
Just reifying #Shadowlands answer.
def myfunc(argument: ArgType): ReturnType {
val response = dependency()
logger.debug(response.member1, response.member2)
response
}

How to bind parameters in replaced expression nodes in Entity Framework on the fly

I'm trying to replace a function call like (simplified) Utility.GetString(MyEntity.SomePropertyWithRelatedEntity)=="abc" with an expression visitor into something like p => p.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag==true).SomePropertyWithRelatedEntity.
It means, the datamodel goes like:
MyEntity -> RelatedEntity -> SubRelatedEntity
I'm trying to return a string value from the SubRelatedEntity, based on some rules in the RelatedEntity, so I don't have to re-write / copy/paste the whole filtering rules in every usage; that's why I put inside a "call-signature", so my expression visitor can identify it and replace the fake-call to Utility.GetString to some complicated lambda expressions.
My expression visitor contains something like:
public override Expression Visit(Expression node)
{
if (node == null)
return null;
Expression result = null;
if (node.NodeType == ExpressionType.Call)
{
MethodCallExpression mce = node as MethodCallExpression;
if (mce.Method.DeclaringType == typeof(Utility) && mce.Method.Name == "GetString")
{
Expression<Func<RelatedEntity, string>> exp = re => re.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag == true).SomeStringValue;
result = exp.Body;
}
else
result = base.Visit(node);
}
else
result = base.Visit(node);
return result;
}
Now, the problem is, the "sre" parameter is not bound when called the injected lambda expression. After much research, I see the lambda parameters should be replaced with another expression visitor, specifically searching for the new parameters and replacing them with the old ones. In my situation, however, I don't have an "old parameter" - I have the expression MyEntity.SomePropertyWithRelatedEntity (e.g. an property filled with the related entities) which I need to insert somehow in the generated lambda.
I hope my problem is understandable. Thank you for any insights!
After getting no answers for long time and trying hard to find a solution, I've solved it at the end :o)! It goes like this:
The newly injected lambda expression gets an ParameterExpression - well, this is a 'helper', used when directly calling the lambda, what I don't want (hence, 'parameter not bound' exception when ToEnumerable is called). So, the clue is to make a specialized ExpressionVisitor, which replaces this helper with the original expression, which is of course available in the Arguments[] for the method call, which I try to replace.
Works like a charm, like this you can reuse the same LINQ expressions, something like reusable sub-queries, instead of writing all the same LINQ stuff all time. Notice as well, that expression calling a method is not allowed in EF, in Linq2Sql it worked. Also, all the proposed web articles only replace the parameter instances, when constructing/merging more LINQ expressions together - here, I needed to replace a parameter with an faked-method-call argument, e.g. the method should not be called, it only stands for a code-marker, where I need to put my LINQ sub-query.
Hope this helps somebody, at the end it's pretty simple and logical, when one knows how the expression trees are constructed ;-).
Bye,
Andrej

Custom control structures in Scala?

There are a number of times I've run into a simple pattern when programming in Java or C++ for which a custom control structure could reduce the boilerplate within my code. It goes something like:
if( Predicate ){
Action
return Value
}
that is, a "return if"-type statement. I've tried making functions with signature like foo[A,B]( pred:((A,A)=>Boolean), value:Option[B] ) but then I wind up checking if I've returned Some or None. I'm tripped up by the return statement.
Is there an inherit way of making such control structures in functional languages or more specifically Scala?
Edit:
I was not as clear with my description and it's confusing people who are trying to help me. The key reason my foo doesn't work is that it can't short-circuit the evaluation of the containing function. That is
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
return_if( withinBounds( geometry, projection ), logToString( logger, "Geometry outside " + projection.toString ), EmptyGeometry() )
return_if( topologicallyCorrect( geometry ), intersect( correct( geometry ), reference )
//rest of the function
}
and still allow for tail recursion within the return_if.
I would use a partial function:
def whatevs[A, B](options : PartialFunction[(A,A), B]) : Option[B] = {
val myInput = generateInput
if(options.isDefined(myInput)) {
Some(options(myInput))
} else None
}
Then your usage could look like the following:
whateves {
case (x,y) if x > y => "Biggerz"
case (x,y) if y > x => "Tiny!"
}
In general, you do not need a return statement. If-expression will evaluate to the last expression used in each block. You may need to help the compiler figure out the type-result of the if expression, but the return is unneeded.
Partial Functions are a mechanism to perform an action if some condition holds true. In the above, the two conditions are x > y or y > x from the tuple.
If the whatevs function is not quite what you're talking about I'd recommend using raw pattern matching.
Hmm, as far as I understand it you want the return in the control structure to exit the function it is embedded in.
So in your example it should exit the method intersect?
I am not sure if thats possible. Because a return inside the return_if will always exit return_if and I don't think there is a way to tell scala, that the return should exit the function return_if is embedded in.
I hope I understood what you wanted to do :)
It looks like you're using this as a conditional escape from the control flow of the code.
You can do this in Scala too (just annotate the method with the type to return) if it's really the most elegant solution to the problem. Sometimes code needs to act like a multi-stage filter, and this pattern works well for that.
Of course you can always nest if-statements, but that gets awkward.
There are a couple of other things to consider in Scala, however. One can
methodReturningOption.getOrElse(
// All the code for the None case goes in here
)
which usually works pretty well at consolidating different branches in the case that there is a sensible default (or you'll end up throwing an exception if there's not).
Alternatively, you can abuse pattern matching for this:
None match { // Could use a real variable instead of None if it helped
case _ if (Predicate1) => Action1; Value1
case _ if (Predicate2) => Action2; Value2
. . .
case _ => ErrorHandlingPerhaps
}
But you also might be able to think about your problem in a different way so that these sort of predicates become less useful. (Without knowing more details, I can't suggest something.)
I am at a loss to understand why you would want this. Here's the code you want to write:
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
return_if( withinBounds( geometry, projection ),
logToString( logger, "Geometry outside " + projection.toString ),
EmptyGeometry() )
return_if( topologicallyCorrect( geometry ),
intersect( correct( geometry )),
reference )
// rest of the function
}
while here's what it looks like in "ordinary" Scala:
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
if (withinBounds( geometry, projection )) {
logToString( logger, "Geometry outside " + projection.toString )
return EmptyGeometry() }
if( topologicallyCorrect( geometry )) {
intersect( correct( geometry ))
return reference }
//rest of the function
}
To me the "ordinary" version looks a lot clearer. For one thing it makes it very clear what is being returned. It's not even more verbose. I suspect you have a more complex use case. If you show us that, maybe we will be able to direct you to patterns that are more appropriate.

; expected but <place your favourite keyword here> found

I'm trying to write a class for a scala project and I get this error in multiple places with keywords such as class, def, while.
It happens in places like this:
var continue = true
while (continue) {
[..]
}
And I'm sure the error is not there since when I isolate that code in another class it doesn't give me any error.
Could you please give me a rule of thumb for such errors? Where should I find them? are there some common syntactic errors elsewhere when this happens?
It sounds like you're using reserved keywords as variable names. "Continue", for instance, is a Java keyword.
You probably don't have parentheses or braces matched somewhere, and the compiler can't tell until it hits a structure that looks like the one you showed.
The other possibility is that Scala sometimes has trouble distinguishing between the end of a statement with a new one on the next line, and a multi-line statement. In that case, just drop the ; at the end of the first line and see if the compiler's happy. (This doesn't seem like it fits your case, as Scala should be able to tell that nothing should come after true, and that you're done assigning a variable.)
Can you let us know what this code is inside? Scala expects "expressions" i.e. things that resolve to a particular value/type. In the case of "var continue = true", this does not evaluate to a value, so it cannot be at the end of an expression (i.e. inside an if-expression or match-expression or function block).
i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
}
This is a problem, as the function block is an expression and needs to have an (ignored?) return value, i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
()
}
() => a value representing the "Unit" type.
I get this error when I forget to put an = sign after a function definition:
def function(val: String):Boolean {
// Some stuff
}