On Wed, Nov 25, 2009 at 1:19 AM, logicmoo@gmail.com wrote:
Alan, Thanks.. yeah that setAccessable is very useful. I helps resolve my temptation to make the jfield/jstatic and jcall secretly always setAccessable if !isAccessable! And the .getDeclared*s is equally important
Which reminds me - currently in ABCLs .java we are going to need to .patch #'jstatic to search the getDeclaredMethods() instead of getMethods() (And a couple other nits)
getDeclaredFields/Methods do not handle inherited members, so to do it correctly you need to recur over superclasses and interfaces. So it could go like this: if "try-harder" or some similar flag is false, look only for getFields/Methods - you'll get all the accessible members of that class, declared or inherited, but not private members. If the flag is true, use getDeclaredXXX on the full type hierarchy of your class. I have (Java) code written for this type of recursion available.
Bye, Alessio
----- Original Message ----- From: "Alan Ruttenberg" alanruttenberg@gmail.com To: dmiles@users.sourceforge.net Cc: "Thomas Russ" tar@isi.edu; "Armed Bear" armedbear-devel@common-lisp.net Sent: Tuesday, November 24, 2009 1:33 PM Subject: Re: [armedbear-devel] SETF for JFEILDS
In case it is of some interest, the code below is what I use with jss. It's main element of interest is the "try-harder" flag, which uses setAccessible to allow setting some fields that would otherwise cause an exception.
(defun get-java-field (object field &optional try-harder) (if try-harder (let* ((class (if (symbolp object) (setq object (find-java-class object)) (if (equal "java.lang.Class" (jclass-name (jobject-class object)) ) object (jobject-class object)))) (jfield (if (java-object-p field) field (find field (#"getDeclaredFields" class) :key 'jfield-name :test 'equal)))) (#"setAccessible" jfield t) (values (#"get" jfield object) jfield)) (if (symbolp object) (let ((class (find-java-class object))) (#"peekStatic" 'invoke class field)) (#"peek" 'invoke object field))))
(defun set-java-field (object field value &optional try-harder) (if try-harder (let* ((class (if (symbolp object) (setq object (find-java-class object)) (if (equal "java.lang.Class" (jclass-name (jobject-class object)) ) object (jobject-class object)))) (jfield (if (java-object-p field) field (find field (#"getDeclaredFields" class) :key 'jfield-name :test 'equal)))) (#"setAccessible" jfield t) (values (#"set" jfield object value) jfield)) (if (symbolp object) (let ((class (find-java-class object))) (#"pokeStatic" 'invoke class field value)) (#"poke" 'invoke object field value))))
On Tue, Nov 24, 2009 at 4:27 PM, logicmoo@gmail.com wrote:
Thanks, you are right, much better to use the built-in key stuff
(defun (setf jfield) (newvalue class-ref-or-field field-or-instance &optional ( instance nil instance-supplied-p) unused-value) (declare (ignore unused-value)) (if instance-supplied-p (jfield class-ref-or-field field-or-instance instance newvalue) (jfield class-ref-or-field field-or-instance newvalue)))
----- Original Message ----- From: "Thomas Russ" tar@ISI.EDU To: dmiles@users.sourceforge.net Sent: Tuesday, November 24, 2009 9:24 AM Subject: Re: [armedbear-devel] SETF for JFEILDS
On Nov 23, 2009, at 6:47 AM, logicmoo@gmail.com wrote:
So actually
(defun (setf jfield) (newvalue class-ref-or-field field-or- instance &optional ( instance :noinst) unusedvalue) (if (eq instance :noinst) (jfield class-ref-or-field field-or-instance newvalue) (jfield class-ref-or-field field-or-instance instance newvalue)))
Would be a little better.. good eye.
For what it's worth, I am not a fan of using special values to determine whether optional (or keyword) arguments are actually passed or not. I prefer to use the predicate forms from the lambda list, so something more like
(defun (setf jfield) (newvalue class-ref-or-field field-or-instance &optional ( instance nil instance-supplied-p) unusedvalue) (declare (ignore unusedvalue)) (if instance-supplied-p (jfield class-ref-or-field field-or-instance newvalue) (jfield class-ref-or-field field-or-instance instance newvalue)))
----- Original Message ----- From: dmiles@users.sourceforge.net To: "Alessio Stalla" alessiostalla@gmail.com Cc: "Armed Bear" armedbear-devel@common-lisp.net Sent: Monday, November 23, 2009 6:27 AM Subject: Re: [armedbear-devel] SETF for JFEILDS
----- Original Message ----- From: "Alessio Stalla" alessiostalla@gmail.com To: dmiles@users.sourceforge.net Cc: "Armed Bear" armedbear-devel@common-lisp.net Sent: Monday, November 23, 2009 5:42 AM Subject: Re: [armedbear-devel] SETF for JFEILDS
On Mon, Nov 23, 2009 at 2:36 PM, logicmoo@gmail.com wrote:
> Does anyone object to adding this to java.lisp? If not could it > be done? > > (defun (setf jfield) > (newvalue class-ref-or-field field-or-instance &optional > ( instance :noinst) (value :novalue)) > (if (eq instance :noinst) > (jfield class-ref-or-field field-or-instance newvalue) > (jfield class-ref-or-field field-or-instance instance newvalue)))
It seems a nice idea to me, but there are a couple of things that I don't understand:
A>- why :noinst and not simply nil?
JFIELD is defined as: class-ref-or-field field-or-instance &optional instance value The valid argument patterns for this operation are: (class-ref field-name): to retrieve the value of a static field. (class-ref field-name instance-ref): to retrieve the value of a class field of the instance. (class-ref field-name primitive-value:) to store primitive-value in a static field. (class-ref field-name instance-ref value): to store value in a class field of the instance. (class-ref field-name nil value): to store value in a static field (when value may be confused with an instance-ref). (field-name instance): to retrieve the value of a field of the instance. The class is derived from the instance. (field-name instance value): to store value in a field of the instance. The class is derived from the instance.
JFIELD doesn't distingusih between static and non static fields
Also cases of "class-ref field-name instance-ref value" (accessing superclass field)
Depending on how the field is defined
(setf (jfield *MyClass* "someStaticBooleanField") NIL) it is distinguable from (setf (jfield *MySuperClass* "nonStaticBooleanField" *my- instance* ) NIL)
A>- value is not used, what's the point of it?
correct the "default :novalue" is not needed. (I was debugging and trying to find corner cases with all those bizzare legal jfield signatures )
but... "value" as an &optional was needed to match the signature of what is legal for jfield so things like this can work:
(define-symbol-macro %iscold (jfield "org.armedbear.lisp.Lisp" "cold")) %iscold ;; ==> NIL (setq %iscold T) ;; ==> T %iscold ;; ==> T (setq %iscold NIL) ;; ==> NIL
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel