Which Clojure methods can I use to create multiple instances on an object and store then in an Java ArrayList?
I know how to do this in Java but I'm not sure how to proceed in Clojure, any help/pointers will be much appreciated
Look at http://clojure.org/java_interop
(doto (new java.util.ArrayList)
(.add (new Object))
(.add (new Object)))
returns #<ArrayList [java.lang.Object#5ae7fa2, java.lang.Object#33d6798]>
There are 2 forms for creating new objects in clojure.
(Classname. args*)
(new Classname args*)
So here is the straightforward example how to create the java object in clojure. Firstly how it looks in Java:
Thread thread = new Thread("Hi there");
Clojure
; return instance of java.lang.Thread class
(new Thread "Hi there")
or another way
(Thread. "Hi there")
why not store in vector?
user=> (def lst (atom []))
user=> (swap! lst conj "String")
user=> (swap! lst conj 123)
user=> #lst
["String" 123]
Related
For the given code below, in Kotlin, it's not possible to execute the function forEach (or anything similar, map, filter, so on...) because BarList is mocked. So the native implementation of forEach and relatives are not being called. After a bit of search on the internet I came with this:
public class BarList<E> extends AbstractList<E> implements OrderedBarCollection<E> {
//...
}
//...
val mockedList: BarList<Foo> = mockBarList()
val fooList = listOf(Foo())
`when`(mockedList.iterator()).thenReturn(fooList.iterator())
`when`(mockedList.size).thenReturn(fooList.size)
com.nhaarman.mockito_kotlin
.doCallRealMethod()
.`when`(mockedList)
.forEach(Mockito.any<Consumer<Foo>>()) //Attempt to call the Consumer.
mockedList.forEach { foo ->
//Not executing
}
I tried this above based on the answer of this question: https://stackoverflow.com/a/49407513/2430555
I also tried:
com.nhaarman.mockito_kotlin.doCallRealMethod().`when`(mockedList).forEach(any())
But it's causing:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
//...
The definition of forEach in the Kotlin source code is:
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit
I think I should replace any() with something that matches action: (T) -> Unit, but I am not sure how to do this.
I don't mind to use interactor if needed, but I need to at least make forEach run as expected. Could you guys please help me?
Regards,
Pedro
The solution is to use thenAnswer instead of thenReturn for the mocked list.
`when`(mockedList.iterator()).thenAnswer { fooList.iterator() }
Reason:
Author: Tobias Berger
an iterator is only good for going through the list once. Therefore
you usually get a new one every time you call the iterator() function.
If you mock that with thenReturn(messageList.iterator()) , it will
just call that once on messageList and reuse that iterator instance
every time you try to get one for your mock. Once your first loop over
this iterator is finished, it will always say it has no more items.
With thenAnswer you define a supplier that is called each time your
mocked function is used, providing a new iterator for each call (as
would be expected)
I think you cannot mock extension funcitons at all, while they are not members of target class.
forEach is Just outer helper for Iterable
In this case you will be still calling usual forEach of kotlin on fooList.
And i don't understand what is the motivation to mock collections especially substitute iterator of mocking OrderedBarCollection with simple ArrayList (listOf), what is requirement to do it?
The zip that accepts iterable is turning my object to Object[] vs the merge. After the zip, I cannot perform other transformation because I lost my object type. Is this the same concept as the stream's reduce combiner? Just wondering how to properly use it. Thanks.
final List<Object[]> list = Flux
.zip(List.of(Mono.just("hello"), Mono.just("world")), objects -> objects)
.collectList().block();
final List<String> strings = Flux
.merge(List.of(Mono.just("hello"), Mono.just("world")))
.collectList().block();
It's an API limitation at present since the generic type of the Iterable's Publisher isn't captured, so that type information isn't available to you in the method. This means you'll unfortunately have to do something unsafe if you want to keep the type information here.
The most trivial change to your current code to get a List<String[]> would be the following:
final List<String[]> list = Flux
.zip(List.of(Mono.just("hello"), Mono.just("world")), objects -> Arrays.stream(objects).toArray(String[]::new))
.collectList().block();
...but of course, you do lose your type safety.
Depending on your use case (generally speaking, if you combinator can combine elements one at a time rather than all in one go), you may also be able to use Flux.zip() in a reducer:
List<Flux<String>> l = new ArrayList<>();
l.add(Flux.just("hello", "me"));
l.add(Flux.just("world", "hungry"));
final List<String> strings = Flux.fromIterable(l)
.reduce((a, b) -> Flux.zip(a, b, (x, y) -> x + ", " + y))
.flatMap(x -> x.collectList())
.block();
It's not equivalent, but may be a type-safe alternative depending on what you need.
Looks like the first argument to the zip function takes a Iterable<? extends Publisher<?>> the question marks mean it can take whatever object.
and its second argument Function<? super Object[],? extends O> is a function that the first argument is "something" that is an object in an array, and the second argument is "something" that extends a concrete type.
So sadly you will be getting a Object[] it's how it is written. You can cast your objects to the correct.
I have never used it before but i played around with it a bit.
final Flux<String> helloWorldString = Flux.zip(List.of(Mono.just("hello"), Mono.just(" "), Mono.just("world")), objects -> {
StringBuilder value = new StringBuilder();
for (var object : objects) {
value.append((String) object);
}
return value.toString();
});
As it is a combinator i think its purpose is to take any objects[] and build a concrete type out if it.
In Python, I would do like this:
class foo:
def __init__(self):
self.x = self
Otherwise, now the object is a parameter of itself. How can I do it in common lisp?
(defclass mn ()
((pai :accessor mn-pai
:initarg :pai
:initform self)))
In a DEFCLASS slot description one can't reference the object itself. But one can write methods for instance initialization. This would be similar to your Python example.
Our class:
? (defclass foo ()
((bar :accessor foo-bar :initarg :foo)))
#<STANDARD-CLASS FOO>
We create an :after method for initialize-instance. This generic function is provided by CLOS and its purpose is to initialize a new instance. The first argument is the instance to initialize. The method will be called by the Lisp system when we create an instance of the class foo.
Using the accessor foo-bar:
? (defmethod initialize-instance :after ((object foo) &key)
(setf (foo-bar object) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
or setting the slot via (setf slot-value).
? (defmethod initialize-instance :after ((object foo) &key)
(setf (slot-value object 'bar) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
Note that we can name the instance parameter with any name: object or even self. But the name has no semantics. Since in CLOS we have multi-dispatch (dispatch can work about more than one argument and there is no default dispatched argument), there is no self semantics.
Now we make and then describe an instance of class foo:
? (describe (make-instance 'foo))
#<FOO #x302000D20C0D>
Class: #<STANDARD-CLASS FOO>
Wrapper: #<CCL::CLASS-WRAPPER FOO #x302000D2B43D>
Instance slots
BAR: #<FOO #x302000D20C0D>
As you can see, the slot bar of that instance has been set to the instance itself.
Note that the initform is evaluated in the lexical context of defclass, but the dynamic context of make-instance. This allows you to define a special variable named *this* (you could use this, but that could be confusing) and use it when you initialize objects.
(defvar *this*)
Define a mixin for classes that may reference *this*:
(defclass knows-this () ())
(defmethod shared-initialize :around ((object knows-this) slot-names &rest args)
(declare (ignore args))
(let ((*this* object))
(call-next-method)))
For example:
(defclass foo (knows-this)
((myself :initform *this*)))
(describe (make-instance 'foo))
#<FOO {100AC6EF13}>
[standard-object]
Slots with :INSTANCE allocation:
MYSELF = #<FOO {100AC6EF13}>
CLOS doesn't have the concept of "this" or "self" because through the use of generic functions, whatever instance is being acted upon is passed as an argument.
So, given your example with the accessor mn-pai:
(setf instance (make-instance 'mn))
(mn-pai instance 1)
Here, instance is passed as an argument to the accessor.
If you created a method:
(defmethod inc-pai (an-mn amount)
(incf (mn-pai an-mn) amount))
Again, you see the instance is passed in as the first argument. So, there's always an explicit argument that you use.
Now consider:
(defmethod inc-both (an-mn another-mn amount)
(incf (mn-pai an-mn) amount)
(incf (mn-pai another-mn) amount))
So, in a normal class based system, where would you put this method? In a Utility class? Is this a "mn" class method? It sort of defies ready categorization.
Now consider:
(defclass mn2 ()
((pai :accessor mn2-pai)))
if we were to do this:
(setf an-mn (make-instance 'mn))
(setf an-mn2 (make-instance 'mn2))
(inc-both an-mn an-mn2)
The second line would fail, as mn2 does not have a mn-pai accessor.
However, this would work:
(defmethod inc-both2 (an-mn another-mn amount)
(incf (slot-value 'pai an-mn) amount)
(incf (slot-value 'pai another-mn) amount))
Because the slot-value is the primitive accessor for CLOS, and both classes have a slot named pai. But, then you don't get to call the accessor function. Rather you're setting the slot directly. Probably not what you want. And, of course, the names are coincidence. There's no relationship between the classes save their similar names and a shared slot name.
But you can then do this:
(defmethod inc-both ((mn an-mn) (mn2 another-mn) amount)
(incf (mn-pai an-mn) amount)
(incf (mn-pai2 another-mn) amount))
This works because the runtime will dispatch based on the types of the parameters. We "know" another-mn is an instance of mn2 because we told the system that it must be when we qualified the argument.
But, again, you can see how in a class based system, there's no "place" for this kind of method. We typically just create a Utility class of some kind and stick these in there, or a regular function in the global namespace.
While CLOS has classes, it's not really a class based system.
This also comes up in multi-inheritance scenarios (which CLOS supports). Who is "self" then?
I often have a class that is composed of a list of another class. For example, I'll have a vector-list class made up of vectors. To avoid writing long statements, I write a method to access the embedded class. However, this method only acts as a getter; I cannot use it to set the slot value. Is there a way to use a method to set a class slot value?
Below is a minimal example:
(defclass vector ()
((name :accessor vector-name
:initarg :name)))
(defclass vector-list ()
((vectors :accessor vector-list-vectors
:initarg :vectors)))
(defun make-vector-list ()
(make-instance 'vector-list
:vectors (list
(make-instance 'vector :name 'v1)
(make-instance 'vector :name 'v2))))
(defmethod access-vector-name ((vt vector-list) vector-idx)
(vector-name (nth vector-idx (vector-list-vectors vt))))
;; returns V1
(print (access-vector-name (make-vector-list) 0))
;; Now, trying to set the same slot returns an error
;; How can I set the slot?
(setf (access-vector-name (make-vector-list) 0) 'new); --> error
The simplest would be to write:
(setf (aref (access-vector-name ...) index) value)`
But if you don't want to expose the fact that you have arrays/vectors, you can define a custom setf expander.
First, only define access-vector-name as a :reader in your class.
Then:
(defun (setf access-vector-name) (newval obj index)
(setf (aref (access-vector-name obj) index) newval))
If the intent is to hide the underlying implementation, maybe access-vector-name is a bad name.
You just need to define a setter method to do this. However your code is not legal as it stands: VECTOR is a defined symbol in the CL package (and in fact names both a function and a type) so defining a class called VECTOR is horribly illegal (and a decent implementation would barf at this). Here is a version of your code with the basic class renamed to VEC, and with a setter method.
(defclass vec ()
;; Don't call it VECTOR since it's a function in CL
((name :accessor vec-name
:initarg :name)))
(defclass vec-list ()
((vecs :accessor vec-list-vecs
:initarg :vecs)))
(defun make-vec-list ()
(make-instance 'vec-list
:vecs (list
(make-instance 'vec :name 'v1)
(make-instance 'vec :name 'v2))))
(defmethod access-vec-name ((vt vec-list) vec-idx)
(vec-name (nth vec-idx (vec-list-vecs vt))))
(defmethod (setf access-vec-name) (new (vt vec-list) vec-idx)
(setf (vec-name (nth vec-idx (vec-list-vecs vt))) new))
CLOS doesn't have a predefined macro to define accessor methods like this, outside class definitions: I'm not sure why but perhaps because cases where it's really a 'pure' accessor like this are relatively uncommon.
I thought this might be built-in, but doesn't seem to be. What's the best way to do populate a new class instance from a hash of properties?
It is indeed built in. You can put # symbols infront of the variables inside the hash:
class Cat
constructor: ({#name, #age}) ->
myCat = new Cat {name:'kitty', age:3}
This is part of "Destructuring Assignment" which you can read about on the coffescript website. It even works with nested objects, arrays and even splats.
You could do something like this:
class Foo
constructor: (params = {}) ->
for key, value of params
this[key] = value
f = new Foo(var1: "foo", var2: "bar")
console.log(f)