Error while generating ToGo after overriding WriteStream#cr

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Error while generating ToGo after overriding WriteStream#cr

Yar Hwee Boon-3
Hi all

I'm getting an error while generating a ToGo application after
overriding WriteStream#cr. Anyway wrong with what I did? To reproduce:

1. File in the package below (which overrides WriteStream#cr with
exactly the same code, my actual code overrides WriteStream#cr so that
it uses String lineDelimiter asByteArray for the socket streams).

2. Generate a ToGo for the sample Notepad application.


| package |
package := Package name: 'cr'.
package paxVersion: 0;
        basicComment: ''.


package methodNames
        add: #WriteStream -> #cr;
        yourself.

package binaryGlobalNames: (Set new
        yourself).

package globalAliases: (Set new
        yourself).

package allResourceNames: (Set new
        yourself).

package setPrerequisites: (IdentitySet new
        add: 'Object Arts\Dolphin\Base\Dolphin';
        yourself).

package!

"Class Definitions"!


"Global Aliases"!


"Loose Methods"!

!WriteStream methodsFor!

cr
        self nextPutAll: String lineDelimiter! !
!WriteStream categoriesFor: #cr!accessing!public! !

"End of package definition"!

"Source Globals"!

"Classes"!

"Binary Globals"!

"Resources"!


Thanks.

HweeBoon


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Ian Bartholomew-19
Yar Hwee Boon wrote:

> I'm getting an error while generating a ToGo application after
> overriding WriteStream#cr. Anyway wrong with what I did? To reproduce:

What's happening is that when you file in your package it overwrites the
default implementation of WriteStream>>cr.  When you deploy the Notepad
application the stripper thinks that your package is not needed (there are
no references to a class defined in it) and removes it - you can see that in
the deployment log.  This leaves the image with no WriteStream>>cr method
and, as that method is used by the stripper itself during deployment, it
generates an error.

There are a number of ways to get around the problem but which is best
depends on the circumstances.  You could just change the package, manually
or automatically, of the WriteStream>>cr method back to Dolphin but must
remember not to resave _your_ package or the method will be lost.  My
personal preference in this is to either save the method source in a .st
file and load it in a package script or actually put the method source in
the script and recompile it when the package is loaded.  You might also need
to set the method's Package or it's category to "must not strip" - I can't
remember offhand.

You must always be a bit careful of such side effects when you change system
methods - it's one of the reasons that it is best, if at all possible, to
avoid doing so.  In this case I would have thought that adding
SocketWriteStream>>cr would have been a _much_ better way of solving the
problem you describe?.

--
Ian

Use the Reply-To address to contact me.
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Bill Schwab-2
Ian,

> There are a number of ways to get around the problem but which is best
> depends on the circumstances.  You could just change the package, manually
> or automatically, of the WriteStream>>cr method back to Dolphin but must
> remember not to resave _your_ package or the method will be lost.  My
> personal preference in this is to either save the method source in a .st
> file and load it in a package script or actually put the method source in
> the script and recompile it when the package is loaded.  You might also
need
> to set the method's Package or it's category to "must not strip" - I can't
> remember offhand.

Categorizing the method as 'must not strip' will (IIRC) not do any good if
its package is removed.  A manual prerequisite would probably work.


> You must always be a bit careful of such side effects when you change
system
> methods - it's one of the reasons that it is best, if at all possible, to
> avoid doing so.  In this case I would have thought that adding
> SocketWriteStream>>cr would have been a _much_ better way of solving the
> problem you describe?.

Agreed.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Ian Bartholomew-19
Bill,

>> it when the package is loaded.  You might also need to set the
>> method's Package or it's category to "must not strip" - I can't
>> remember offhand.
>
> Categorizing the method as 'must not strip' will (IIRC) not do any
> good if its package is removed.  A manual prerequisite would probably
> work.

That bit of my comment was really referring to recreating the method in the
package script, resulting in a method that is not actually owned by the
package being loaded .  In the original example the loose WriteStream>>cr
method would be removed from the package and the package's post-install
script edited to read (something like) ...

WriteStream compile: '
cr
    "new"
    self nextPutAll: String lineDelimiter'

When the package was loaded the WriteStream>>cr method would be replaced but
(I've now tried it to see exactly what happens) the replaced method is still
in the original method's package (Dolphin in this case) and the method
categories are unchanged.  Deploying Notepad now works as the stripping
proceeds as if the original WriteStream>>cr method was still present.

It's not a technique that should be overused :-) but it can help avoid
problems if an existing default image method really _must_ be replaced by a
loaded package.

--
Ian

Use the Reply-To address to contact me.
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Yar Hwee Boon-3
In reply to this post by Ian Bartholomew-19
"Ian Bartholomew" <[hidden email]> wrote in message news:<i7qnc.1166$[hidden email]>...

> What's happening is that when you file in your package it overwrites the
> default implementation of WriteStream>>cr.  When you deploy the Notepad
> application the stripper thinks that your package is not needed (there are
> no references to a class defined in it) and removes it - you can see that in

Am I right to assume that it is then fairly compulsory to read the
deployment log not only for errors, but for any stripping of my
packages and also to test the ToGo application (again, as testing has
already been done in-image). OTOH, does it mean that the necessary
base packages, especially the Dolphin package (which contains the
original WriteStream#cr) has not been stripped because there was a
class reference to one of its classes?

>
> You must always be a bit careful of such side effects when you change system
> methods - it's one of the reasons that it is best, if at all possible, to
> avoid doing so.  In this case I would have thought that adding
> SocketWriteStream>>cr would have been a _much_ better way of solving the
> problem you describe?.

My original intent was to avoid duplicating the "self nextPutAll:"
part of the original method, so I did

WriteStream>>cr
        self nextPutAll: self class lineDelimiter

and added a class lineDelimiter when necessary. That's relatively
unimportant so I suppose I shall just add SocketWriteStream>>cr as you
have suggested, the other methods of working around it seems to be
meant as more drastic measures :)


Thanks!

Hwee Boon


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Ian Bartholomew-19
Yar Hwee Boon wrote:

> Am I right to assume that it is then fairly compulsory to read the
> deployment log not only for errors, but for any stripping of my
> packages

I normally only turn logging on if something has obviously gone wrong with
the stripping process or deployed application.

>         and also to test the ToGo application (again, as testing has
> already been done in-image).

That's always a good idea :-) but in my, probably limited, experience I have
found that the Dolphins image stripping doesn't cause that many problems.

>       OTOH, does it mean that the necessary
> base packages, especially the Dolphin package (which contains the
> original WriteStream#cr) has not been stripped because there was a
> class reference to one of its classes?

If you look at the deployment log for an application then you can see a
chronological listing of the actions the stripper takes.  The Dolphin
package itself will be retained but unwanted classes and methods defined
within it will be recursively removed as the stripping progresses

> My original intent was to avoid duplicating the "self nextPutAll:"
> part of the original method, so I did
>
> WriteStream>>cr
> self nextPutAll: self class lineDelimiter

I may be missing something here but from your first post I got the
impression that this was all because you wanted to send a ByteArray to the
SockectWriteStream rather than a String i.e. you wanted to replace

self nextPutAll: String lineDelimiter

with

self nextPutAll: String lineDelimiter asByteArray

If that's the case I'm not sure it's necessary.  The following code can be
evaluated without error and shows that the SocketWriteStream accepts
ByteArrays or Strings.

s := Socket port: 12345 host: 'localhost'.
ss := SocketWriteStream on: s.
ss nextPutAll: #[1 2 3 4].
ss nextPutAll: String lineDelimiter.
ss nextPutAll: 'hello world'.
ss contents

--
Ian

Use the Reply-To address to contact me.
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Error while generating ToGo after overriding WriteStream#cr

Yar Hwee Boon-3
"Ian Bartholomew" <[hidden email]> wrote in message news:<kDGnc.1499$[hidden email]>...

> If that's the case I'm not sure it's necessary.  The following code can be
> evaluated without error and shows that the SocketWriteStream accepts
> ByteArrays or Strings.
>
> s := Socket port: 12345 host: 'localhost'.
> ss := SocketWriteStream on: s.
> ss nextPutAll: #[1 2 3 4].
> ss nextPutAll: String lineDelimiter.
> ss nextPutAll: 'hello world'.
> ss contents

Yes, my bad, and I can't recall how I led myself to believe it was
necessary. You are right, but at least I learnt something out of the
mistake, thanks :)

Hwee Boon