[armedbear-devel] SETF for JFEILDS

Alessio Stalla alessiostalla at gmail.com
Wed Nov 25 08:06:24 UTC 2009


On Wed, Nov 25, 2009 at 1:19 AM,  <logicmoo at 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 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
>>>
>>
>
>
> _______________________________________________
> 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