From: Tamas K Papp on
Hi,

I want to allocate an instance of a class without running
initialize-instance (which would perform some checks on initargs,
those I want to bypass because I am initializing the slots manually).

I think that I have to call allocate-instance, but when I try

(allocate-instance (find-class 'my-class))

I get an error condition (which SBCL is "unable to display", so I must
have screwed up heavily). What's the proper way to do what I want?

Thanks,

Tamas


From: Zach Beane on
Tamas K Papp <tkpapp(a)gmail.com> writes:

> Hi,
>
> I want to allocate an instance of a class without running
> initialize-instance (which would perform some checks on initargs,
> those I want to bypass because I am initializing the slots manually).

This question seems upside-down to me. What checks cause problems when
you want to initialize the slots manually?

Zach
From: Captain Obvious on
TKP> I think that I have to call allocate-instance, but when I try

TKP> (allocate-instance (find-class 'my-class))

TKP> I get an error condition (which SBCL is "unable to display", so I must
TKP> have screwed up heavily). What's the proper way to do what I want?

Well, allocate-instance itself works fine:

CL-USER> (defclass test1 () (a))
#<STANDARD-CLASS TEST1>
CL-USER> (allocate-instance (find-class 'test1))
#<TEST1 {C5C9AA1}>


If it doesn't work with your class, it is some problem you have in your
code.

E.g. one way to implement this error:

CL-USER> (defmethod print-object ((o test1) stream)
(format stream "#<TEST1 a=~a>" (slot-value o 'a)))

CL-USER> (allocate-instance (find-class 'test1))

Unable to display error condition
[Condition of type UNBOUND-SLOT]
0: ((SB-PCL::FAST-METHOD SLOT-UNBOUND (T T T)) #<error printing object>)
1: (SB-PCL::SLOT-UNBOUND-INTERNAL #<error printing object>)
2: ((SB-PCL::FAST-METHOD PRINT-OBJECT
(TEST1 T)) #<error printing object>)
3: (SB-PRETTY:OUTPUT-PRETTY-OBJECT #<error printing object>)
4: (SB-IMPL::STRINGIFY-OBJECT #<error printing object>)
5: (PRIN1-TO-STRING #<error printing object>)


That is, forget to initialize a slot and write a print-object which uses
that slot, and you'll get "Unable to display" thing.

By the way, you might want to use shared-initialize (it is more flexible
than initialize-instance) after allocate-instance, but it is not strictly
necessary, depends on your goal.

From: Tamas K Papp on
On Thu, 13 May 2010 13:34:42 -0400, Zach Beane wrote:

> Tamas K Papp <tkpapp(a)gmail.com> writes:
>
>> Hi,
>>
>> I want to allocate an instance of a class without running
>> initialize-instance (which would perform some checks on initargs, those
>> I want to bypass because I am initializing the slots manually).
>
> This question seems upside-down to me. What checks cause problems when
> you want to initialize the slots manually?

A particular object represents a multivariate t distribution, and is
initialized with the mean, sigma (which is proportional to the
variance), and the degrees of freedom. The INITIALIZE-INSTANCE :AFTER
method checks that the arguments make sense.

But internally, the mean and sigma are used to create a multivariate
normal distribution (in the INITIALIZE-INSTANCE :AFTER method), and t
variates are drawn using the standard algorithm. In some cases, I
have this object directly from intermediate calculations, so instead
of

(make-instance 'mv-t :mean (mean mv-normal) :sigma (variance mv-
normal) :nu nu)

I can just use

(let ((rv (allocate-instance (find-class 'mv-t))))
(setf (slot-value rv 'mv-normal) mv-normal)
...)

Tamas
From: Tamas K Papp on
On Thu, 13 May 2010 21:15:33 +0300, Captain Obvious wrote:

> TKP> I think that I have to call allocate-instance, but when I try
>
> TKP> (allocate-instance (find-class 'my-class))
>
> TKP> I get an error condition (which SBCL is "unable to display", so I
> must TKP> have screwed up heavily). What's the proper way to do what I
> want?
>
> Well, allocate-instance itself works fine:
>
> CL-USER> (defclass test1 () (a))
> #<STANDARD-CLASS TEST1>
> CL-USER> (allocate-instance (find-class 'test1)) #<TEST1 {C5C9AA1}>
>
>
> If it doesn't work with your class, it is some problem you have in your
> code.
>
> E.g. one way to implement this error:
>
> CL-USER> (defmethod print-object ((o test1) stream)
> (format stream "#<TEST1 a=~a>" (slot-value o 'a)))
>
> CL-USER> (allocate-instance (find-class 'test1))
>
> Unable to display error condition
> [Condition of type UNBOUND-SLOT]
> 0: ((SB-PCL::FAST-METHOD SLOT-UNBOUND (T T T)) #<error printing
> object>) 1: (SB-PCL::SLOT-UNBOUND-INTERNAL #<error printing object>)
> 2: ((SB-PCL::FAST-METHOD PRINT-OBJECT
> (TEST1 T)) #<error printing object>)
> 3: (SB-PRETTY:OUTPUT-PRETTY-OBJECT #<error printing object>) 4:
> (SB-IMPL::STRINGIFY-OBJECT #<error printing object>) 5:
> (PRIN1-TO-STRING #<error printing object>)
>
>
> That is, forget to initialize a slot and write a print-object which uses
> that slot, and you'll get "Unable to display" thing.

Thanks, my problem was something similar.

> By the way, you might want to use shared-initialize (it is more flexible
> than initialize-instance) after allocate-instance, but it is not
> strictly necessary, depends on your goal.

I think it makes my code more standard and compact, so it was useful.

Tamas
 |  Next  |  Last
Pages: 1 2
Prev: ECL 10.4.1
Next: clbuild/darcs hangs on get?