In JavaScript you can do the following:
var obj = {
property: 1,
method1: function() {
//...
},
method2: function() {
//...
}
};
obj.method1()
I am wondering if there is a groovy equivalent for this (a map containing a method). I know this is just like a class, but I dont want a class ha..
Yes, you can put closures inside a map. But this is not the way to get
objects in Groovy. There is no concept of "this", that knows about the
map.
def obj = [
inc: { it + 1 }
]
println obj.inc(10)
Ok so Javascript is not OOP. They have OBJECTS but that is it. What you are showing is an OBJECT.
In Groovy, you can do this with a class that can instantiate the object and then you can do that on the object. For example you can create a CommandObject (which is what you are probably wanting) and then fill in the properties like you want or fill them in on instantiation. For example (using above example):
def paramsDesc = new ParamsDescriptor()
paramsDesc.paramType = 'paramtype'
paramsDesc.keyType = 'keyType'
paramsDesc.name = 'name'
paramsDesc.idReferences = 'id'
paramsDesc.description = 'desc'
paramsDesc.mockData = 'mock'
paramsDesc.values = []
OR (if you create a constructor) you can instantiate all at once:
def paramsDesc = new ParamsDescriptor('paramtype','keyType','name','id','desc','mock',[])
CommandObjects can have methods and functions (like above). But you just have to instantiate them first (def paramsDesc = new ParamsDescriptor())
This is the difference between a class and an object; think of a class as the blueprint and the object as what is created from the blueprint.
Related
Is it possible with MapStruct 1.2 to map a source property with a specific value to a specific different value in the target?
I think about something like this:
public abstract class JiraKpmMapper {
#Mappings({
#Mapping(source = "mySource.propA", target = "myTarget.propX")
})
#ValueMappings({
#ValueMapping(source = "ABC", target = "XYZ"),
#ValueMapping(source = "123", target = "789")
})
public abstract MyTarget source2Target(final MySource mySource);
}
So that when MapStruct sees during the mapping that when mySource.propA has the value "ABC" myTarget.propX needs to be set to value "XYZ" and so forth.
To be more precisely, I even want something more elaborated:
The target should be a class haven three properties in which the resulting target value must be split into.
For instance, if mySource.propA has the value "ABC" the target myTarget should get a value like "V01.123.456.AB". This value in turn shall be split up in a preValue, a middleValue and an endValue:
preValue = "V01"
middleValue = "123.456"
endValue = "AB"
whereby there's no property holding the complete result string.
That's why I already wrote a custom mapper and I tell the MyMapper to use it via
#Mapper(componentModel = "spring", uses = MyCustomMapper.class)
This works so far but I can't achieve it to tell the MyCustomMapper to put "V01.123.456.AB" into the target when the souzrce comes with "ABC".
You can't really do that with MapStruct. The #ValueMapping annotation is for mapping of Enum(s).
In order to achieve what you are looking for you would need to do that in #BeforeMapping or #AfterMapping.
For example you can do something like:
#Mapper
public interface JiraKpmMapper {
#BeforeMapping
default void beforeMapping(#MappingTarget MyTarget target, MySource source) {
if (source.getPropY().equals("ABC") {
target.setPropX("V01.123.456.AB");
}
}
#Mapping(target = "propX", ignore = true) // This is now mapped in beforeMapping
MyTarget source2Target(final MySource mySource);
}
Your custom mapper then should have an #AfterMapping. Where you would convert the propX into your class. You can even do this as part of the #BeforeMapping I wrote and directly create your class (or invoke the method that does the conversion from String into a class)
you can do something like this
#Mapping(target = "myTarget.propX",expression="java(mySource.getPropA().equals(\"Abc\")?"\"V01.123.456.AB\":\"\")")
I'm trying to parse a JSON data and assign it to a POJO in Grails.
I started with
obj.param=jsonRequest.jsonWrap.attrib.something.jsonParam
After some experimenting and refactoring, it looks like this now.
jsonRequest.jsonWrap.attrib.something.with {
obj.param1=jsonParam1
obj.param2=jsonParam2
//...
}
}
Now, can I avoid the repeated use of obj reference?
I'm imagining that your actual starting point is something like the following. On the JSON side:
import groovy.json.JsonSlurper
String jsonText = '''{
"jsonWrap":{
"attrib":{
"something":{
"jsonParam1": "value1",
"jsonParam2": "value2",
"jsonParam3": "value3",
"jsonParam4": "value4",
"jsonParam5": "value5"
}
}
}
}'''
def jsonRequest = new JsonSlurper().parseText(jsonText)
On the Groovy side:
class ObjectType {
def param1, param2, param3, param4, param5
}
def obj = new ObjectType()
Now, if I had any control over how either the JSON side or the Groovy side are defined then I would do my darnedest to ensure that the property names of the JSON "something" object are exactly the same as the property names in the Groovy "ObjectType" class. For example, like this:
class ObjectType {
def jsonParam1, jsonParam2, jsonParam3, jsonParam4, jsonParam5
}
Then, unmarshalling the "something" object into Groovy is as simple as this:
def obj = new ObjectType(jsonRequest.jsonWrap.attrib.something)
Only one reference to the JSON object. Only one reference to the Groovy object. And the former is used to instantiate the latter. And furthermore, notice that there is no need to reference the properties at all. That is, JSON objects from the slurper are instances of Map, so if the property names match up, you can use the default "Map constructor" syntax.
If, however, you do not control property naming in either set of objects, I would still recommend a different Map-based short-cut. First define a constant Map from one set of property names to the other, like so:
def map = [param1:"jsonParam1", param2:"jsonParam2", param3:"jsonParam3",
param4:"jsonParam4", param5:"jsonParam5"]
Then I would use something like this for the object unmarshalling:
def obj = new ObjectType().with { o ->
jsonRequest.jsonWrap.attrib.something.with { j ->
map.each { oParam, jParam -> o[oParam] = j[jParam] }
}
o
}
i don't think there is a trivial way to trick groovy into "use objectA, if getting is needed and objectB for setting". If obj above is a map or you can apply a map to this object, then you could produce a map in your with block and use this. If you have to have nested structures then more work is needed.
def jsonParam = new Expando([ p1: 'p1', p2: 'p2', p3: 'p3', ])
def obj = new Expando(
jsonParam.with{
[
param1: p1,
param3: p3,
] // `with` will return this map
})
assert obj.param1==jsonParam.p1
assert obj.param3==jsonParam.p3
I use expandos for simple code.
Does swift not have nested classes??
For example, I can't seem to access the property test of the master class from the nested class.
class master{
var test = 2;
class nested{
init(){
let example = test; //this doesn't work
}
}
}
Swift's nested classes are not like Java's nested classes. Well, they're like one kind of Java's nested classes, but not the kind you're thinking of.
In Java, an instance of an inner class automatically has a reference to an instance of the outer class (unless the inner class is declared static). You can only create an instance of the inner class if you have an instance of the outer class. That's why in Java you say something like this.new nested().
In Swift, an instance of an inner class is independent of any instance of the outer class. It is as if all inner classes in Swift are declared using Java's static. If you want the instance of the inner class to have a reference to an instance of the outer class, you must make it explicit:
class Master {
var test = 2;
class Nested{
init(master: Master) {
let example = master.test;
}
}
func f() {
// Nested is in scope in the body of Master, so this works:
let n = Nested(master: self)
}
}
var m = Master()
// Outside Master, you must qualify the name of the inner class:
var n = Master.Nested(master:m)
// This doesn't work because Nested isn't an instance property or function:
var n2 = m.Nested()
// This doesn't work because Nested isn't in scope here:
var n3 = Nested(master: m)
This solution is sort of similar to how I use it in C#, and I have successfully tested it in Xcode.
Here's a breakdown of the process:
Your nested class needs to be made optional so you don't have to initialize it, so theres a '?' in the declaration; if you initialize both your parent class and your nested class, you end up with a 'recursion' effect and an error is generated
Create a regular function that receives an argument of the same type as your main class
Pass that argument to your nested class (this can go into the nested object's normal initializer). - Since objects are passed by reference by default, there's nothing special to get your nested class to link to the parent class
Inside your nested class, you need a variable of the same type as your parent class
From here on out set up everything as you normally would.
In the code execution area, your nested class object also needs to be regarded as optional (hence the '?'). If you forget about it, Xcode will add it anyways.
In this example, I wanted to design a keyword "set," so when I set variables, I can type:
testClass.set.(and then a descriptive method name)
Here is the code, and its goal is to output "test" in the console, after the value is set via the nested object:
class testClass
{
var test_string:String = ""
var set: class_set?
func construct_objects(argument: testClass)
{
self.set = class_set(argument: argument)
}
class class_set
{
var parent:testClass
init(argument: testClass)
{
parent = argument
}
func test_string_to_argument(argument: String)
{
parent.test_string = argument
}
}
}
var oTestClass = testClass()
oTestClass.construct_objects(oTestClass)
oTestClass.set?.test_string_to_argument("test")
print(oTestClass.test_string)
Nested for Swift and Java
Swift has Nested Types definitions
Java has more complex hierarchy of nested class
Swift's Nested is more similar to Java's Static Nested, as a result you do not have an access to properties of outer class. To get access of outer class you can pass it as a parameter.
Example java code is below if I have a class Movie
In java I will create its array by writing below code
Movie[] a = new Movie[4];
but how I can do it in rails So that when I check it on the console
#> a.type
#> "Movie"
Reather than
#> ActiveRecord::Relation
You just create a class by inherited from Array like below,
class MyArray < Array
#Add you custom methods
end
my_array = MyArray.new([1,2,3,4,5]) or
my_array = MyArray.new
my_array[0] = 1
my_array[1] = 2
That enough for basic customization of array data structure.
Literal translation would be
a = (1..4).map { Movie.new }
or (in Rails)
a = (1..4).map { Movie.create! }
but you normally shouldn't need to do it, since unlike in Java, you don't have limited-size arrays in Ruby.
Also, the type of that would then be Array (or rather its class; basic Ruby objects don't have type); the type of an element of that, a[0] for example, would be a Movie.
In the end, not quite sure what you're asking here...
I'm trying to create an object oriented implementation in Lua, for example:
Parent = {
ChildVariable = "Hello",
ChildFunction = function ()
print(Parent.ChildVariable)
end
}
What I would like is rather than doing Parent.ChildVariable I can do ChildVariable instead; it is in the table so I thought must be some way to access it.
Parent = {
ChildVariable = "Hello",
ChildFunction = function(self)
print(self.ChildVariable)
end
}
Parent:ChildFunction()
Lua has a special construct for that: the colon operator.
The two following lines are equivalent:
tbl.func(tbl)
and
tbl:func()