Smalltalk - collection is empty error when saving - smalltalk

Does anyone know what would cause this? I can't save anything to my class because I get a debugging exception thrown: Collection is empty
Link to source: https://dl.dropboxusercontent.com/u/1817765/Pharo%20Crash%20Files.rar
Steps to recreate:
Launch Pharo 1.1
Select the .image file, without the .changes file in the same directory
Attempt to select NumberWithUnits>>=
Crash
Attempt to save almost anything to NumberWithUnits
Crash

The issue was that I didn't have the correct .changes file associated with my project. Since my teammate and I were collaborating, these were lost in translation. Once I placed the correct .changes files in the directory of my .image file, everything worked out.

Squeak/Pharo have special handling in case of absent source code: they try and decompile CompiledMethod from appropriate MethodDictionary.
What you saw here is a failure of Decompiler to properly decompile some method.
Without code, the IDE is non functional, and you are stuck (you can't save your code, browse your code, debug your code...)
This Pharo 1.1 version is very old and you won't get any support on it.
But interestingly, the bug of Decompiler that you encountered is still present on current Squeak trunk development (4.5)
And the method that makes the Decompiler loosy is:
< aNumberWithUnits
(self compareUnits: aNumberWithUnits)
ifTrue: [self value: ((aNumberWithUnits value) < (self value) ifTrue: [^true] ifFalse: [^false]).]
ifFalse: [^Error new signal: 'Incompatible unit types.'].
This is a rather unconventional code since the message [self value: ...] will never be sent.
The reason is that the parameter will be evaluated first, and both branches of the condition will return ifTrue: [^true] ifFalse: [^false].
Since you explored some dark corner that only newbies do explore, and that we failed to test, I'd just say thank you.
If you feel like it, you can open a report on http://bugs.squeak.org

Related

How do I start Etoys from Squeak?

In the Squeak System Browser, I see that there are many class categories related to Etoys:
But how do I access Etoys from Squeak? How do I get something like the screenshot shown below?
(Source of Etoys screenshot: https://commons.wikimedia.org/wiki/File:Squeak_screenshot.png)
There are also Squeak versions set up specifically for Etoys, e.g.:
https://squeak.js.org/etoys/#fullscreen
I think there is easier way than Leandro is proposing.
Just run the Workspace from the menu where you type:
Project enterNewWithInitialBalloons
Select it with mouse and run it - Do it (alt+d). Application should start. I'm unfamiliar with the application. To me it looks similar to the picture you show.
Edit: how did I find it?
I searched through the source code. I have to agree that this is not straight forward.
First I tried to find anything that has to do with Etoys project/class. I tried to find anything that would indicate that you can start it.
This way I found Etoys-Experimental package with class EToysLauncher. The word launcher to me sounded like it could be launched. I looked at the class of the EToysLauncher where I found instance creating protocol where you can find these methods (remember we are still at the experimental package!):
#buildGallery
#buildPanel
#openGallery
#openPanel
If you go through these e.g. EToysLauncher openPanel you will get a message doesNotUnderstand: #latestProjectVersionsFromFileEntries. I then started to investigate the Walkback. I tried to check what is the issue here. I got this message because of the last line ^ Project latestProjectVersionsFromFileEntries: entries.
I went to the Project>>latestProjectVersionsFromFileEntries: to check what it is actually doing. In meantime I have inspected the values from the entries variable in the debugger. In the entries I could find an OrderedCollection but nothing what would satisfy #('*.pr' '*.pr.gz' '*.project') from the method. So I thought to myself, that perphaps the Project itself could satisfy it.
I went to the Project class and protocol Etoys-Squeakland-instance creation where I found two methods #enterNew and #enterNewWithInitialBalloons.
The #enterNew gives doesNotUnderstand: #newMorphicOn: so I skipped that one and tried the #enterNewWithInitialBalloons, which worked and since it is in the protocol Etoys-Squeakland-instance creation I came to the conclusion it has create Etoys-Squeakland new instance.
Edit: Show shared flaps?
Yes, you can activate the flaps also via Show shared flaps.
There is, however, quite a difference between running the Project enterNewWithInitialBalloons and Showing the shared flaps via Preferences.
If you start the Etoys via the Project enterNewWithInitialBalloons you will start completely new project (your currently opened windows will be hidden). To see your previous windows you need to either Porojects/Enter Project and switch to the HomeProject or you have to close the newly opened project via Projects/Close This Project.
The source that shows it is:
enterNewWithInitialBalloons
| newP |
newP := MorphicProject new.
newP world addMorph: (DoCommandOnceMorph new extent: 1#1; actionBlock: [SugarNavigatorBar putUpInitialBalloonHelp]; yourself).
newP enter.
This creates new MorphicProject and to this project it adds new Morph.
On the other hand, if you start it with Preferences/Show shared flaps the flaps will be just added to your current environment without creating a new project.
The source that shows it is: Preferences class >>sharedFlapsSettingChanged
sharedFlapsSettingChanged
"The current value of the showSharedFlaps flag has changed; now react"
self showSharedFlaps "viz. the new setting"
ifFalse:
[Flaps globalFlapTabsIfAny do:
[:aFlapTab | Flaps removeFlapTab: aFlapTab keepInList: true]]
ifTrue:
[Smalltalk isMorphic ifTrue:
[self currentWorld addGlobalFlaps]]
The self currentWorld addGlobalFlaps adds the flaps to the currentWorld. The PasteUpMorph>>addGlobalFlaps creates new PasteUpMorph and adds it.
You can also notice the difference also in the menu bar title Untitled vs. HomeProject.

Pharo: menu error

I broke something in my Pharo image, but i don't know exactly what. Now when I try to file-out my package to insert in a new image, I only see 'Why you see this menu' and 'Debug'. If I run menu debug in the playground, I get a FallbackMenu.
How can I fix this error?
EDIT: When I try to click on my package, The system browser is acting very weird an the following error pops up: link
Using Max's your code, i get 2 nil keys:
The first one is a mistake in my code (I assigned a class binding to nil instead of a instance variable with the same name). But I can't edit this because I can't access it through the System Browser.
The second one is ActiveEvent. I don't know where this comes from and whether this or the previous nil causes the System Browser to act weird
One possibility is that you nilled a class binding. Inspect the following to get a list of keys and values that are nil:
Smalltalk globals associations select: [ :assoc |
assoc value isNil or: [
assoc key isNil ] ].
BTW: rather then attaching a screen shot it would help if you attached the stack. To get the stack trace, right click on the topmost entry in the stack list (the one that's selected in your screen shot) and select "Copy to clipboard". Then paste the contents (or at least the first 30 frames) here.
Update
ActiveEvent seems normal. I have the same. The second one is very likely problematic. You may be able to cheat your way out by removing the entry:
Smalltalk globals removeKey: nil.
If done a quick try and it seems to work.

xCode: Accessing properties of an object via console

Is it possible to access the properties of objects in xCode console?
If I try the following I get an error that he property doesn't exist.
po someObject.someprop
If I don't breakpoint the code and run the app it works fine so I know someObject.someprop exists. I don't think I have the grasp on xCode console yet? What I loved about Flex/Flash development is that I could set a break point and in the console window or variables view I could traverse every structure down to the ends of the earth.
I could see SomeDicionary[key].someArray[1].someObject.prop and it would show me the value. Is this not possible in xCode console or is there a trick to get to it?
You'll actually have to use the bracket syntax notation:
po [someObject someprop]
The debugger is sometimes very finnicky about syntax. This is filled with all sorts of helpful tips for debugging in XCode.
Just a side note, variables/properties declared in the implementation file (*.m) instead of the header file (*.h) can sometimes be invisible to the debugger variable list display depending on if the breakpoint is in that class's code, because of scope. Not necessarily required here, but useful to know seeing as how it is kind of relevant.

EXC_BAD_ACCESS on animationForKey:

I'm trying to use a recent feature of the Scintilla component, which provides OSX-like text-highlighting effect (the yellow animated bouncing box), and I'm stuck with an error that pops up intermittently :
EXC_BAD_ACCESS
pointing to this particular line :
if (layerFindIndicator!=nil)
if ([layerFindIndicator animationForKey:#"animateFound"])
[layerFindIndicator removeAnimationForKey:#"animateFound"];
(the ifs are mine; just in case I caught the object layerFindIndicator being nil, or deallocated or whatever... Unfortunately, it doesn't help...)
layerFindIndicator is seemingly a subclass of CAGradientLayer. (You may see the full code for layerFindIndicator, here).
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
Since, I'm an absolute newbie to Quartz Core, could please give me any hint as to HOW this could be debugged?
This doesn't have anything to do with QuartzCore specifically (at least, I hope not)—it's general this-object-has-been-killed-before-its-time-how-do-I-find-the-killer stuff.
In Xcode:
Edit your current scheme.
For the Profile action, set it to use the Debug build configuration.
Dismiss that and then hit the Profile command.
Xcode will build for that action and then launch Instruments.
Instruments will prompt you to choose a template; you want the Zombies template. Once you've chosen it, Instruments will create a trace document and run your application. Switch to your application (if it isn't already frontmost), then do whatever causes the crash.
If the crash really is a dead-object crash, Zombies will reveal it. You'll get a flag in Instruments's timeline saying something like “message sent to zombie object 0xd3c2b1a0”, and your program will probably exit shortly thereafter.
In that flag is a tiny little button that looks like this: ➲ except it'll be gray. Click on it.
That takes you to the history of that object (actually of that address, including any previous objects or other allocations that have started at that address). Show your Extended Detail Pane (the one that appears on the right showing a stack trace), then scroll down to the end and then move backward (upward) step by step through time, looking at releases and autoreleases, looking for the one that isn't balancing out the object's allocation or a retain.
The solution will probably involve one or more of:
Changing a property to be strong or weak rather than assign/unsafe_unretained
Adding a property where you previously did not strongly own an object
Rearchitecting some things, if it's not clear which of the above you need to do or if either one of them seems like a filthy hack
Switching to ARC to get weak properties and __weak instance variables (both of which get set to nil automatically when the referenced object dies) and to get local variables being implicitly initialized to nil
But it'll depend on what you find in Instruments. And, of course, there's the chance that your problem—the bad access—isn't a dead object at all and all of the above will not help you.
Try this:
if (layerFindIndicator!=nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}
Also check to see if it is released else were.
EDIT:
Another thing I found was you didn't have an white space in the if. Your code should now look like this:
if (layerFindIndicator != nil){
if ([layerFindIndicator animationForKey:#"animateFound"]){
[layerFindIndicator removeAnimationForKey:#"animateFound"];
}
}

How can I work around "Xcode could not locate source file"

I'm working with the ID3 framework in Xcode (which has since disappeared off the face of the web - including google cache!).
I'm testing out an import mp3 feature which allows them to edit the tags as they import them. One of the test cases is a corrupt or invalid mp3 with no proper id3 header. The problem I'm having is that when updating the tags of the invalid mp3 (updateFile:), the ID3 framework attempts to use id3V1Tag.m (I assume it falls back to this if it can't find the v2 tag) and this is where I get the Xcode error (whilst running the program, not building):
Xcode could not locate source file: id3V1Tag.m (line: 299)
Even in a release build this crashes the program, so it's not something I can really ignore.
I've tried putting a try/catch block around it but it's not treated as an exception so doesn't get caught. The function to load the tag data for the file returns a BOOL but it appears this only returns false if the given file doesn't exist, so this doesn't help either.
Current code:
[tagData release];
tagData = [[TagAPI alloc] initWithGenreList:nil];
tagsLoaded = [tagData examineFile:exportPath];
if(tagsLoaded) {
[tagData setTitle:title];
[tagData setArtist:artist];
[tagData setComments:comments];
#try {
[tagData updateFile];
}
#catch (id e){
NSLog(#"h");
}
}
The error you're getting is that Xcode is trying to locate your source file id3V1Tag.m in order to show it during debugging. No code you write will affect this.
If you don't have the id3V1Tag.m source file in your framework distro, there's nothing you can do about this, and there's little to do but ignore it (other than seeing if you can avoid causing it to be requested, like not setting a breakpoint in it, not stepping into it, and not crashing in it).
If you do have it, and are building it, then perhaps you're not building with the right debug information, so you'll have to tell us more about your build setup.
So the problem you're having is that your program is crashing when you attempt to compile id3V1Tag.m or while running the program. I'm a bit confused on that.
If its crashing while running maybe this is an issues with a code file missing from a library? How are you reading the ID3 tag information exactly? Is it through your own code or through a 3rd party library/class.