What does the following warning mean: 'side-effecting nullary methods are discouraged'? - function

I have a lot of nullary methods (methods with 0 parameters) in my scala test file. Hence, instead of writing them as :
def fooBar() = //
I write them as :
def fooBar = //
I get the following warning when I do so:
Warning:(22, 7) side-effecting nullary methods are discouraged: suggest defining as `def fooBar()` instead
What is the meaning of the warning? I am using intelliJ as my IDE and could not really find much about this warning on the web.
EDIT
And, I forgot to mention, when I use the brackets, the warning does not appear.

The common convention for nullary methods is to:
in case it's a side-effecting method, signify it with use of parenthesis
otherwise, drop parenthesis in case it's pure accessor-like method with no side effects
You're breaking this rule and IDE warns you about this.
See also https://stackoverflow.com/a/7606214/298389

Does fooBar have side-effects?
It's simply stating a good practice to define a side-effecting method as such:
def fooBar() = ...
And non-side-effecting methods like this:
def fooBar = ...
Since the method call looks similar to accessing a val, it's good to differentiate when the method is doing more than just returning a value.

Related

Learning About constructors in Python

I have recently learnt about Exception Handling concepts. I am not able to understand why self.arg=arg doesnt work whereas self.msg=arg works in the below code.
class MyException(Exception):
def init(self,arg):
self.msg=arg
def check(key,value):
print('Name={} Balance={}'.format(key,value))
if(v<2000):
raise MyException('Balance amt is less in the account of ',key)
bank={'Raj':5000,'Vikas':10000,'Nishit':500,'John':321211}
for k,v in bank.items():
try:
check(k,v)
except MyException as obj:
print(obj)
It should work. You're basically assigning the value of the argument arg to the instance variable arg, no conflict there, a classic example that can be found here in Documentation.
Maybe you mistyped, used a symbol from another alphabet, or forgot a spacebar on that line? Without the error message all I can do is guess. So try replacing msg in your working code with arg once again, it may fix the problem.
By the way, it would be easier to use f-strings instead of formatting:
f'Name={key} Balance={value}'
f'Balance amt is less in the account of {key}'
It's shorter, you don't have to worry about messing up the order or number of arguments, and the code is more readable.

Calling mock method instead of real method with Mockito

I have a method which needs to be called instead of the real method.
Instead I get an exception. Can somebody please help me with right way to call the alternate method through mockito ?
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 4 recorded.
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
//Code starts here
class A{
public realMethod(String s, Foo f){
}
}
class B {
public mockMethod(String s, Foo f) {
}
}
class UnitTestClass{
ClassA mock = new ClassA();
mock.when(realMethod(any(String.class), any(Foo.class))).thenReturn(mockMethod(any(String.class),any(Foo.class));
}
You are getting mocking wrong.
Here:
thenReturn(mockMethod(any(String.class),any(Foo.class));
That simply doesn't make sense.
Mocking works like this:
you create a mock object of some class, like A mock = mock(A.class)
you specify interactions on that mock object
Your code implies that you think that these specifications are working like "normal" code - but they do not!
What you want to do: when some object is called with certain parameters, then return the result of another method call.
Like in:
when(a.foo(x, y)).thenReturn(b.bar(x, y))
That is what want you intend to do. But thing is: it isn't that easy. You can't use the any() matcher in thee thenReturn part in order to "provide" the arguments that were passed in the when() call before! It is that simply.
Mocking should be within a specific unit test to get a specific result.
Meaning: you are not writing an ordinary program where it would make any sense to "forward" parameters to another call. In other words; your code should more look like:
when(mock.realMethod("a", someSpecificFoo)).thenReturn(mockMethod("a", someSpecificFoo))
That is the only thing possible here.
Beyond that, you might want to look into a Mockito enter link description here instead.
Long story short: it simply looks like you don't understand how to use mocking frameworks. I suggest that you step back and read/work various tutorials. This is not something you learn by trial and error.

How add custom behavior to copy function in case classes in scala?

Is it possible o add custom behavior to copy function in case classes?
Something like this:
case class User (version: Integer) { //other fields are omitted
//something like this
override def copy (...) {
return copy(version = version + 1, ...)
}
}
So I do not want to rewrite copy function, just add increasing version field and copy others. How can I do that?
Adding behavior to fundamental functions such as copy is not a good idea. The functional approach is to let data be just data, and to have the behavior in the functions that operate on the data from outside.
But if you really want to do it, you will just have to re-implement the copy method, like this:
case class User(name:String, age:Int, version:Int = 0) {
def copy(name:String = this.name, age:Int = this.age) = User(name,age,version+1)
}
Usage:
scala> User("John Doe", 25).copy(age = 26)
res4: User = User(John Doe,26,1)
But note that you will probably have to re-implement some other methods as well for useful behavior. For example, you might not want people to be able to pass a version when constructing a user. So you need to make the constructor private and add an apply method.
You also might not want the version field to be considered for equality. So you have to redefine equals and hashCode to omit the version field. So since you have redefined almost everything that a case class gives you, you might as well make the class a normal non-case class.
In general, I think case classes should be used for pure data, while more object oriented classes that mix data and logic are best done as normal classes, even if it means a bit more typing.

Is there a way to avoid using 'call' in Coffeescript?

I'm writing a simple Twitter client to play with coffeescript. I have an object literal with some functions that call each other via callbacks.
somebject =
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize( this.afterLogin.call this )
afterLogin: ->
this.getTweets(this.pollinterval)
This code works perfectly. Edit: actually this.afterlogin should be sent as a callback above, not ran immediately, as Trevor noted below.
If, within authenticateAndGetTweets, I removed the 'call' and just ran:
oauth.authorize( this.afterLogin )
and don't use 'call', I get the following error:
Uncaught TypeError: Object [object DOMWindow] has no method 'getTweets
Which makes sense, since 'this' in afterLogin is bound to the thing that initiated the callback rather than 'someobject' my object literal.
I was wondering if there's some magic in Coffeescript I could be doing instead of 'call'. Initially I thought using the '=>' but the code will give the same error as above if '=>' is used.
So is there a way I can avoid using call? Or does coffeescript not obviate the need for it? What made '=>' not work how I expected it to?
Thanks. I'm really enjoying coffeescript so far and want to make sure I'm doing things 'the right way'.
As matyr points out in his comments, the line
oauth.authorize( this.afterLogin.call this )
doesn't cause this.afterLogin to be called as a callback by oauth.authorize; instead, it's equivalent to
oauth.authorize this.afterLogin()
Assuming that you want this.afterLogin to used as a callback by oauth.authorize, megakorre's answer gives a correct CoffeeScript idiom. An alternative approach supported by many modern JS environments, as matyr points out, would be to write
oauth.authorize( this.afterLogin.bind this )
There's no CoffeeScript shorthand for this, partly because Function::bind isn't supported by all major browsers. You could also use the bind function from a library like Underscore.js:
oauth.authorize( _.bind this.afterLogin, this )
Finally, if you were to define someobject as a class instead, you could use => to define afterLogin such that it's always bound to the instance, e.g.
class SomeClass
foo: 'bar'
authenticateAndGetTweets: ->
console.log "Authorizing using oauth"
oauth = ChromeExOAuth.initBackgroundPage(this.oauthdetails)
oauth.authorize(this.afterLogin)
afterLogin: =>
this.getTweets(this.pollinterval)
someobject = new SomeClass
you can put a lambda in the function call like so
auth.authorize(=> #afterLogin())
You have to use either the call or apply methods because they set the scope of the function (the value of this). The error results because the default scope is the window object.

Why do I get a "Too many input arguments" error when not passing any?

I am working on some simple object-oriented code in MATLAB. I am trying to call one of my class methods with no input or output arguments in its definition.
Function definition:
function roll_dice
Function call:
obj.roll_dice;
When this is executed, MATLAB says:
??? Error using ==> roll_dice
Too many input arguments.
Error in ==> DiceSet>Diceset.Diceset at 11
obj.roll_dice;
(etc...)
Anyone have any ideas what could be causing it? Are there secret automatic arguments I'm unaware that I'm passing?
When you make the call:
obj.roll_dice;
It is actually equivalent to:
roll_dice(obj);
So obj is the "secret" automatic argument being passed to roll_dice. If you rewrite the method roll_dice to accept a single input argument (even if you don't use it), things should work correctly.
Alternatively, if you know for sure that your method roll_dice is not going to perform any operations on the class object, you can declare it to be a static method as Dan suggests.
For more information on object-oriented programming in MATLAB, here's a link to the online documentation.
I believe you can also get around this by declaring roll_dice to be a static method.