Groovy - Set your own property of an Integer - groovy

I just started to learn Groovy and wondering if you can set your own property for an integer. For example,
def a = 34.5.plus(34.34)
def b = 5.64.minus(3.43)
def c = 12.64.multiply(33.43)
In the above there are certain methods like plus minus and multiply
What should I do if I want to define some of my own methods for integers like that.
I searched Google but couldn't find much about it.

Sure, you can just add methods to the metaClass of Integer.
Here's an example:
Integer.metaClass.zeds = { -> 'z' * delegate }
assert 3.zeds() == 'zzz'
You can also add methods to a single instance of integer should you wish to, ie:
Integer num = 4
num.metaClass.halved = { -> delegate / 2.0 }
assert num.halved() == 2.0
You can also add methods to classes via Extension Methods a good explanation of which can be found over here
It should be noted (as you originally tagged this question as Java) that obviously, Java code will have no knowledge of these things, as it doesn't know about the metaClass

Use groovy meta programming, this allows you to create dynamic method creation atruntime in the class that you want to place in .
bydefault if a method is not found methodmissing exception throws , this is where groovy allows you add method at runtime for more reference use the below comprehensive link
http://groovy-lang.org/metaprogramming.html
If this answer helps , dont forget to click answered.

Related

Parameterizing Objects in spock

I have a problem with parameterizations of list of object by using spock where block. It seems the ListInput value is not taking from the where clause and always coming null value. I have verified the same feature for string and other primitive types and it is working fine.
Does Spock support parameterizations objects ? If yes what is the issue here .
def "check Param Of List of Objects"()
{
expect:
def a= hasflag(ListInput);
a== flag
where:
ListInput | flag
BOList1 | true
BOList2 | false
}
Here the type of BOList1 is an java ArrayList contains the object
You haven't really provided enough information for a definitive answer but I'll try to help.
The where block isn't exactly just a block of code, it's more like a number of parameters passed to a method. It can do a lot, but sometimes you need to pass your code a little differently.
Of note:
- Void methods aren't allowed (but you can get around this using .with{} )
- An iterative parameter cannot also be a derived parameter (constructed from other parameters)
- If you're referencing class level variables (defined within the class but outside this test) they need to be given the #Shared annotation for your tests to have access.
Given more information about where your lists are coming from will help me give better advice.
Final tip; explicitly typecast your parameters to see if that gives you anymore information
def "check Param Of List of Objects"(ArrayList listInput, boolean flag) {
expect:
flag == hasflag(ListInput);
where:
listInput | flag
BOList1 | true
BOList2 | false
}

C# use reflection to get method name [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
get methodinfo from a method reference C#
This is most likely something simple but so far I have not come up with anything on how to do this.
I want to be able to get the name of a method in two different ways. Please note I want a method name, not a property name.
1) Inside of a class like ClassA<T>, looking like:
var name = GetMethodName(x => x.MethodA);
2) Outside of a class, looking like:
var name = GetMethodName<ClassA<object>>(x => x.MethodA);
var name = GetMethodName<ClassB>(x => x.MethodB);
How might I do this exactly?
Thanks!
You don't need lambdas (x => x.MethodA, etc). That's just confusing the issue (and hiding the method of interest: the MethodA bit would be hidden from your GetMethodName method).
Instead, you can use reflection to get a MethodInfo object, which then has a Name property.
For example:
MethodInfo sm = typeof(SomeClass).GetMethod("SomeMethod");
string methodName = sm.Name;
Here methodName will be the string "SomeMethod". (Of course, in this simple case we've used the class name to get the MethodInfo object, so it's somewhat circular and we might as well have just used the hard-coded "SomeMethod" string instead!)

Is it possible to define a new operator in Groovy?

Is it possible to define a brand new operator in Groovy? I would like to express a trade where someone buys 200 items for the price of 10 like this:
def trade = 200 # 10
Is this achievable?
Thanks
EDIT: I want to make it clearer that I am interested in defining an operator not adding a method. Cheers.
We always wanted the ability to define an operator through the user in Groovy, but so far we haven't gotten around the problems that come along with that. So the current state is that Groovy does not support custom operators, only the ones that are already in use.
I am not quite sure how you can make this work for the # sign but you could certainly add the operation like this which I actually find more expressive:
Number.metaClass.buyFor { Integer price ->
delegate * price
}
def result = 200.buyFor(10)
println result
Number.metaClass."#" {Integer x -> delegate * x}
assert (2.'#' (2)) == 4
The official documentation has a section on Operator Overloading: https://groovy-lang.org/operators.html#Operator-Overloading
Here is a list from the docs:

Can I redefine String#length?

I'd like to re-implement a method of a Java class. For example, for "hi".length() to return 4. (How) Can I do that?
I know using SomeClass.metaClass I can get a reference to an existing method and define new (or overriding) method, but I can't seem to be able to do that for existing Java methods.
Using Groovy, you can replace any method (even those of final classes) with your own implementation. Method replacement in Groovy uses the meta-object protocol, not inheritance.
Here's the example you requested, i.e. how to make String.length() always return 4
// Redefine the method
String.metaClass.invokeMethod = { name, args ->
def metaMethod = delegate.metaClass.getMetaMethod(name, args)
def result = metaMethod.invoke(delegate, args)
name == 'length' ? 4 : result
}
// Test it
assert "i_do_not_have_4_chars".length() == 4
Seems like it could be possible by abusing String metaClass. But the attempt I've done so far in groovy console didn't led to the expected result :
def oldLength = String.metaClass.length
String.metaClass.length = { ->
return oldLength+10;
}
println "hi".length()
outputs the sad 2
I think you could take a look at Proxy MetaClass or Delegating metaClass.
If you did redefine it, it would only work in Groovy code. Groovy can't change the way Java code executes.
In Groovy, "hi".length() is roughly equivalent to this Java:
stringMetaClass.invokeMethod("hi","length");
Because Groovy doesn't actually call length directly, metaClass tricks work in Groovy code. But Java doesn't know about MetaClasses, so there is no way to make this work.
Although this question is very old I like to point out another way (at least for newer Groovy versions) .
The length() method in java.lang.String is implemented from java.lang.CharSequence interface. In order to reimplement the method using the String-metaClass you need to "override" the method in the metaClass of the interface first.
CharSequence.metaClass.length = { -> -1}
String.metaClass.length = { -> 4 }
assert "i_do_not_have_4_chars".length() == 4
The solution using String.metaClass.invokeMethod changes the behaviour of all String-methods and is problematic. For instance, simply invoking "asdf".size() leads to an exception on my setup.

Groovy type conversion

In Groovy you can do surprising type conversions using either the as operator or the asType method. Examples include
Short s = new Integer(6) as Short
List collection = new HashSet().asType(List)
I'm surprised that I can convert from an Integer to a Short and from a Set to a List, because there is no "is a" relationship between these types, although they do share a common ancestor.
For example, the following code is equivalent to the Integer/Short example in terms of the
relationship between the types involved in the conversion
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
def c = new Child1() as Child2
But of course this example fails. What exactly are the type conversion rules behind the as operator and the asType method?
I believe the default asType behaviour can be found in: org.codehaus.groovy.runtime.DefaultGroovyMethods.java
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.java.
Starting from DefaultGroovyMethods it is quite easy to follow the behavior of asType for a specific object type and requested type combination.
According to what Ruben has already pointed out the end result of:
Set collection = new HashSet().asType(List)
is
Set collection = new ArrayList( new HashSet() )
The asType method recognizes you are wanting a List and being the fact HashSet is a Collection, it just uses ArrayList's constructor which takes a Collection.
As for the numbers one, it converts the Integer into a Number, then calls the shortValue method.
I didn't realize there was so much logic in converting references/values like this, my sincere gratitude to Ruben for pointing out the source, I'll be making quite a few blog posts over this topic.

Resources