[armedbear-devel] SETF for JFEILDS

Alan Ruttenberg alanruttenberg at gmail.com
Tue Nov 24 21:33:33 UTC 2009


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20091124/0905bf76/attachment.html>


More information about the armedbear-devel mailing list