[armedbear-devel] SETF for JFEILDS

logicmoo at gmail.com logicmoo at gmail.com
Wed Nov 25 00:19:59 UTC 2009


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)


----- Original Message ----- 
From: "Alan Ruttenberg" <alanruttenberg at gmail.com>
To: <dmiles at users.sourceforge.net>
Cc: "Thomas Russ" <tar at isi.edu>; "Armed Bear" <armedbear-devel at 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 at 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 at ISI.EDU>
>> To: <dmiles at 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 at 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 at users.sourceforge.net>
>> > To: "Alessio Stalla" <alessiostalla at gmail.com>
>> > Cc: "Armed Bear" <armedbear-devel at common-lisp.net>
>> > Sent: Monday, November 23, 2009 6:27 AM
>> > Subject: Re: [armedbear-devel] SETF for JFEILDS
>> >
>> >
>> >>
>> >> ----- Original Message -----
>> >> From: "Alessio Stalla" <alessiostalla at gmail.com>
>> >> To: <dmiles at users.sourceforge.net>
>> >> Cc: "Armed Bear" <armedbear-devel at 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 at 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 at common-lisp.net
>> > http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
>>
>>
>> _______________________________________________
>> armedbear-devel mailing list
>> armedbear-devel at common-lisp.net
>> http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
>>
> 





More information about the armedbear-devel mailing list