Is there a way to make squeak remember what variables have been set to in the past? So as I'm browsing the source it will tell me which type of object a variable contained last time that bit of code was running? _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
>>>>> "peter" == peter h meadows <[hidden email]> writes:
peter> Is there a way to make squeak remember what variables have been set to peter> in the past? So as I'm browsing the source it will tell me which type peter> of object a variable contained last time that bit of code was running? Nope, but you can either record the type (maybe write something to Transcript) or capture it in the debugger. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Hummm. How much work would it be to add this ability to the browser? And roughly how would I go about it? Thanks. On Mon, 2 Jun 2008, Randal L. Schwartz wrote: > Date: Mon, 02 Jun 2008 19:34:36 -0700 > From: Randal L. Schwartz <[hidden email]> > To: peter h meadows <[hidden email]> > Cc: [hidden email] > Subject: Re: [Newbies] remembering variables > >>>>>> "peter" == peter h meadows <[hidden email]> writes: > > peter> Is there a way to make squeak remember what variables have been set to > peter> in the past? So as I'm browsing the source it will tell me which type > peter> of object a variable contained last time that bit of code was running? > > Nope, but you can either record the type (maybe write something to Transcript) > or capture it in the debugger. > > -- > Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 > <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> > Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. > See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion > Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
>>>>> "peter" == peter h meadows <[hidden email]> writes:
peter> Hummm. How much work would it be to add this ability to the browser? And peter> roughly how would I go about it? Thanks. Because it's not part of a normal development process with smalltalk? I don't *care* what types things are, as long as they don't throw a "does not understand" error when I call various methods with them. What do you think you'll be doing with the knowledge of "the most recent class a variable has been assigned"? How will you use it in your development? -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Oh. I'm still very new to smalltalk. It seemed like it would help me to understand what's going on. I wanted it to remember everything. E.g if the thing is an array it will tell me what has been stored in it. Also, wouldn't it help with code completion? If it knows what type of object it was in the past it can guess which messages I want to send to it. That would be useful. > > peter> Hummm. How much work would it be to add this ability to the browser? And > peter> roughly how would I go about it? Thanks. > > Because it's not part of a normal development process with smalltalk? > > I don't *care* what types things are, as long as they don't throw > a "does not understand" error when I call various methods with them. > > What do you think you'll be doing with the knowledge of "the most recent class > a variable has been assigned"? How will you use it in your development? > Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
>>>>> "peter" == peter h meadows <[hidden email]> writes:
peter> Oh. I'm still very new to smalltalk. It seemed like it would help me to peter> understand what's going on. I wanted it to remember everything. E.g if peter> the thing is an array it will tell me what has been stored in it. Also, peter> wouldn't it help with code completion? If it knows what type of object peter> it was in the past it can guess which messages I want to send to peter> it. That would be useful. But the problem is that a given type in the past is not any indication of a type in the future. You're not "thinking smalltalk" yet. Stop worrying about types. :) Oh, and they aren't types. They're instances of classes. If you want to see what's going on, learn to single step in the debugger. It's quite informative. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Ah. Well, more often than not the variables in my code stay as one 'type' of thing. And I thought that generally they would otherwise things would get really confusing!? Sometimes when I try to understand how a program is working I get lost in the debugger. What I'd like is a kind of overview of what's going on. Something I can browse and focus in on the parts that seem interesting. In theory I can do this with the system browser but it doesn't tell me how everything fits together. I want to see an overview of how all the parts fit together.. Who uses what.. Which bits are connected.. The order in which things are done, etc. Can I get the debugger to show a tree of message sends, that I can browse? Something like that? Any ideas? thx. >>>>>> "peter" == peter h meadows <[hidden email]> writes: > > peter> Oh. I'm still very new to smalltalk. It seemed like it would help me to > peter> understand what's going on. I wanted it to remember everything. E.g if > peter> the thing is an array it will tell me what has been stored in it. Also, > peter> wouldn't it help with code completion? If it knows what type of object > peter> it was in the past it can guess which messages I want to send to > peter> it. That would be useful. > > But the problem is that a given type in the past is not any indication of > a type in the future. > > You're not "thinking smalltalk" yet. Stop worrying about types. :) > > Oh, and they aren't types. They're instances of classes. > > If you want to see what's going on, learn to single step in the debugger. > It's quite informative. > Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
>>>>> "peter" == peter h meadows <[hidden email]> writes:
peter> Can I get the debugger to show a tree of message sends, that I can browse? peter> Something like that? Well, the debugger is always showing an execution stack. And you can ask the code browser to show all senders and implementors of the various messages in each method. Is that what you're looking for? -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by peter h meadows
Hi Peter,
I went to a college where they only taught Java, so hopefully I can help you a little. In school, I was taught that the 3 tenets of object oriented programming are encapsulation, inheritance, and polymorphism. That may be true, but only if one chooses to ignore history (which reminds me, I should call up Johns Hopkins and ask for most of my tuition back). In Smalltalk: "OOP ... means only messaging, local retention, protection, and hiding of state-process, and extreme late-binding of all things". The focus is on sending and receiving messages between objects, regardless of their types. I can understand your desire to know the type of each variable beforehand, if that's the style of development that you are most familiar with. But try this. First, read this article on the Squeak debugger. After, look at a unit test, add a halt somewhere in the implementation code, and run that unit test. The debugger will pop up. The debugger is like a stack trace, only you can inspect every object in this frozen process (including their types). Once you are familiar enough with the Smalltalk and the debugger, you may find that C++/Java/C# type systems are a pain. However, if type-free development doesn't suit your tastes, but you are still looking for a language which offer high levels of abstraction, you may want to look into Haskell. Me, I feel more productive with Lisp dialects and Smalltalk. You said you're still new to Smalltalk - I can recommend a few books that helped me, if you're interested. Hope you found this somewhat helpful, Bill Six On Mon, Jun 2, 2008 at 8:57 PM, peter h meadows <[hidden email]> wrote:
_______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by peter h meadows
On Tue, 03 Jun 2008 05:57:48 +0200, peter h meadows wrote:
> Ah. Well, more often than not the variables in my code stay as one > 'type' of thing. And I thought that generally they would otherwise > things would get really confusing!? For this part of your question use Squeak's explorer. Try (World explore) to get an idea what it is about, for example expand the submorph branches that you see there. > Sometimes when I try to understand how a program is working I get lost > in the debugger. What I'd like is a kind of overview of what's going on. For this part of your question try (MessageTally spyOn: [Object compileAll]). > Something I can browse and focus in on the parts that seem interesting. For MessageTally the parts of a computation which really do something are interesting. > In theory I can do this with the system browser but it doesn't tell me > how everything fits together. I want to see an overview of how all the > parts fit together.. Who uses what.. Which bits are connected.. The > order in which things are done, etc. MessageTally tells you how the parts of your computation fit together, who's using what, and the order in which things are done. > Can I get the debugger to show a tree of message sends, that I can > browse? Something like that? Yes, MessageTally does that for you: a tree of message sends. From the Spy results, you can select a class and browse it for more details, or a method and browse its senders or implementors for more details. > Any ideas? thx. > > > >>>>>>> "peter" == peter h meadows <[hidden email]> writes: >> >> peter> Oh. I'm still very new to smalltalk. It seemed like it would >> help me to >> peter> understand what's going on. I wanted it to remember everything. >> E.g if >> peter> the thing is an array it will tell me what has been stored in >> it. Also, >> peter> wouldn't it help with code completion? If it knows what type of >> object >> peter> it was in the past it can guess which messages I want to send to >> peter> it. That would be useful. >> >> But the problem is that a given type in the past is not any indication >> of >> a type in the future. >> >> You're not "thinking smalltalk" yet. Stop worrying about types. :) >> >> Oh, and they aren't types. They're instances of classes. >> >> If you want to see what's going on, learn to single step in the >> debugger. >> It's quite informative. >> _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by peter h meadows
Hello Peter,
phm> Can I get the debugger to show a tree of message sends, that I can browse? phm> Something like that? I should have a ready made reply for this: Cris Muller, author of Magma created the TracingMessagesBrowser. This shows senders and implementors in an indented List. What you have to know is you can drag over messages in the indented list to select many and with shift right click (on windows) you get "remove from this browser". You need this when you implement a message with a name that everybody loves and your implementors shows you a hundred implementors. Search the archives of Squeak dev and most important, get it from Squeak map. You'll like it. An algorithm encompasses 10 classes and you can work on it in *one* window. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Klaus D. Witzel
Hello Klaus,
KDW> Yes, MessageTally does that for you: a tree of message sends. From the Spy KDW> results, you can select a class and browse it for more details, or a KDW> method and browse its senders or implementors for more details. interesting idea to use it this way! But MessageTally IMHO only shows what it finds on the stack when it peeks. So it can miss some methods running seldom and quick. So you can do MessageTally>>tallySends: [your tallied block] which uses the simulator (sloow!!) but gets you everything. And to be real useful with long class names and deeply nested sends one might have to patch some of the class side methods of MessageTally in the defaults category. After looking I see it has become better with 3.9 so the latter applies only for 3.8 and older. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
How do I use TracingMessagesBrowser? If I try to install it with 'Squeak Map Package Loader' I get Error: No installer found for package. (this happens in every image that I've tried). If I try to install it from MC I open the repo and click on the mcz and squeak hangs. when interrupted it says it was in HTTPSocket(OldSocket)>>waitForDataUntil: I noticed TracingMessagesBrowser is in the FunSqueak image so I tried that but I don't see any way to open it. So confusing. Thanks in advance for your help. _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
I found something explaining the TracingMessagesBrowser and it works in the FunImage, but I still can't install it in any other image. "When you browse Squeak code, one of the browsers you will invariably use VERY frequently is a Methods browser. This browser appears whenever you browse "senders" or "implementors" of a method, or references to a class or variable, among other things. It is a two-paned browser, methods list in the upper-pane, code in the lower-pane. So just keep exploring code normally, the next time you use senders or implementors (something any Smalltalker does about 1000 times per day) you will see the Tracing Messages Browser. These browsers look the same initially, but by having the "traceMessages" preference set, they take on enhanced behavior as you "trace" method calls. The SqueakMap entry describes it well: "I look like a standard methods browser with methods in the upper pane, code in the lower. As you browse senders and implementors, the upper pane is built into a "stack" rather than opening new method browsers, reducing window profileration. Implementors are indented below the currently selected method, senders are outdented above. You end up with a flow of the execution of methods across multiple classes all in one place. The stack is quickly customized by easy-removal of unwanted methods. First, the upper pane is multi-select, and can handle rapid, sweeping gestures of the mouse without dropping selections (shift+clicking is also supported). Once methods are selected, you can quickly remove them (just from the browser) with otherwise unused Command+f." I think this browser has saved me years of closing windows. " _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by peter h meadows
El 6/5/08 5:14 AM, "peter h meadows" <[hidden email]> escribió: > I noticed TracingMessagesBrowser is in the FunSqueak image so I tried that > but I don't see any way to open it. TracingMessagesBrowser don't open new windows. Instead, when you navigate the system looking for senders or implementors, etc, all go to top window instead opening new windows . Any troubles with FunSqueak , I wish know _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners Picture 2.png (18K) Download Attachment |
In reply to this post by peter h meadows
El 6/5/08 5:14 AM, "peter h meadows" <[hidden email]> escribió: > I noticed TracingMessagesBrowser is in the FunSqueak image so I tried that > but I don't see any way to open it. And here you have the .sar, works in several Squeaks, including still in progress SqueakLightII (unoficial Squeak 3.11) Edgar _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners Tracing Messages Browser.2.sar (36K) Download Attachment |
In reply to this post by peter h meadows
>>>>> "peter" == peter h meadows <[hidden email]> writes:
peter> "I look like a standard methods browser with methods in the upper pane, code peter> in the lower. As you browse senders and implementors, the upper pane is built peter> into a "stack" rather than opening new method browsers, reducing window peter> profileration. Implementors are indented below the currently selected method, peter> senders are outdented above. You end up with a flow of the execution of peter> methods across multiple classes all in one place. The stack is quickly peter> customized by easy-removal of unwanted methods. First, the upper pane is peter> multi-select, and can handle rapid, sweeping gestures of the mouse without peter> dropping selections (shift+clicking is also supported). Once methods are peter> selected, you can quickly remove them (just from the browser) with otherwise peter> unused Command+f." Unless I'm missing something, I quickly stopped using it because it didn't let me *choose* which method to follow in either the senders or implementors like a standard browser does. I often look at a method, see a few methods I don't totally get, and ask for *senders* of them not implementors. So it's the wrong direction for me. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Hello Randal,
RLS> Unless I'm missing something, I quickly stopped using it because it RLS> didn't let me *choose* which method to follow in either the senders RLS> or implementors like a standard browser does. I often look at a method, RLS> see a few methods I don't totally get, and ask for *senders* of them RLS> not implementors. So it's the wrong direction for me. this is just the opposite of what I experience. When I press the senders or implementors button in TMB I get a popup with all possible senders and implementors. The method I'm in being the topmost. There was a version where only Alt m or Alr n (windows) in a Refactoring browser would bring up TMB while the buttons there would call up the standard tool but this was fixed soon. I'm still using 3.8.2 though and TMB is one of my most often used tool. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Herbert König
Herbert König a écrit :
> Hello Klaus, > > > KDW> Yes, MessageTally does that for you: a tree of message sends. From the Spy > KDW> results, you can select a class and browse it for more details, or a > KDW> method and browse its senders or implementors for more details. > > interesting idea to use it this way! But MessageTally IMHO only shows > what it finds on the stack when it peeks. So it can miss some methods > running seldom and quick. > > So you can do MessageTally>>tallySends: [your tallied block] which > uses the simulator (sloow!!) but gets you everything. > > And to be real useful with long class names and deeply nested sends > one might have to patch some of the class side methods of MessageTally > in the defaults category. > > After looking I see it has become better with 3.9 so the latter > applies only for 3.8 and older. > Another possibility well beyond beginners list is the opposite, when you want to trace senders call stack rather than sent call tree. The idea is like putting a halt in a method and debugging, but instead of putting a halt, you raise (signal) a Notification in the method(s) you want to trace, and instead of a debugger at each send occurence, you open a MessageTally for tracing the call stacks of the overall sends. Create a subclass of Notification for that purpose, say YourNotification, and put the sentence: YourNotification signal. in every method or block you want to trace. You can of course raise YourNotification conditionally like say: yourConditionsAreFulfilled ifTrue: [YourNotification signal]. Then trap and tally YourNotification with this little code snippet (As demonstrated at http://bugs.squeak.org/view.php?id=6755 I used it with EndOfStream): "INITIALIZE THE TALLY (that is hackish)" tally := MessageTally new. tally spyEvery: 100 on: ['em ezilaitini ot si siht' reverse]. tally class: World class method: World class>>#doOneCycle. "ARM A TIMER TO END THE TALLY" tallyEnd := false. [(Delay forSeconds: 300) wait. tallyEnd := true] fork. "EMULATE REGULAR SQUEAK USER ACTIVITY LOOP" [[World doOneCycle. Processor yield. tallyEnd] whileFalse] "TALLY THE CALL STACK AT EACH SENT OF YOUR METHODS" on: YourNotification do: [:exc | tally tally: exc signalerContext by: 1. exc resume]. "OPEN A WINDOW WITH TALLY CALL STACK RESULTS" (StringHolder new contents: (String streamContents: [:s | tally report: s])) openLabel: 'YourNotification Spy Results'. tally close. You put the code snippet in a workspace and execute it (DoIt). Thanks to [World doOneCycle] emulation this enables you to run any activity you like during the 300 seconds duration including interactive and graphical activity but also running some SUnit tests cases if you want to. Thanks to YourNotification Exception handling, the tally will catch each and every send to the method(s) of interest (where you raised YourNotification), rather than randomly analyze callStack every few milliseconds. Some core or UI activity are really impossible to debug with a halt and step by step processing in debugger, in which case this hack is usefull. (like tracing a Font or a Morphic bug / see http://bugs.squeak.org/view.php?id=1035 or http://bugs.squeak.org/view.php?id=2084 for example). Of course, you do not catch each and every possible send of the method(s), but only actual send you triggered by your selected activity. It's complementary to browsing activity when polymorphism makes it complex to track... You can change the 300 seconds timer at will, or end the tally manually by executing tallyEnd := true with a doIt in the same workspace rather than forking a timer... If you omit the final tally close, you can also cumulate tallies by rearming the timer and tally block (simply doIt!). Though i tried to be didactic, I know this hack might be just too much for this list, but isn't it amazingly clear and powerful what you can do with Smalltalk in a few lines? Just invent your own variations... Nicolas _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
El 6/5/08 7:19 PM, "nicolas cellier" <[hidden email]> escribió: > Herbert König a écrit : >> Hello Klaus, >> >> >> KDW> Yes, MessageTally does that for you: a tree of message sends. From the >> Spy >> KDW> results, you can select a class and browse it for more details, or a >> KDW> method and browse its senders or implementors for more details. >> >> interesting idea to use it this way! But MessageTally IMHO only shows >> what it finds on the stack when it peeks. So it can miss some methods >> running seldom and quick. >> >> So you can do MessageTally>>tallySends: [your tallied block] which >> uses the simulator (sloow!!) but gets you everything. >> >> And to be real useful with long class names and deeply nested sends >> one might have to patch some of the class side methods of MessageTally >> in the defaults category. >> >> After looking I see it has become better with 3.9 so the latter >> applies only for 3.8 and older. >> > > > Another possibility well beyond beginners list is the opposite, when you > want to trace senders call stack rather than sent call tree. > > The idea is like putting a halt in a method and debugging, but instead > of putting a halt, you raise (signal) a Notification in the method(s) > you want to trace, and instead of a debugger at each send occurence, you > open a MessageTally for tracing the call stacks of the overall sends. > > Create a subclass of Notification for that purpose, say > YourNotification, and put the sentence: > YourNotification signal. > in every method or block you want to trace. > You can of course raise YourNotification conditionally like say: > yourConditionsAreFulfilled ifTrue: [YourNotification signal]. > > Then trap and tally YourNotification with this little code snippet > (As demonstrated at http://bugs.squeak.org/view.php?id=6755 I used it > with EndOfStream): > > > > "INITIALIZE THE TALLY (that is hackish)" > tally := MessageTally new. > tally spyEvery: 100 on: ['em ezilaitini ot si siht' reverse]. > tally class: World class method: World class>>#doOneCycle. > > "ARM A TIMER TO END THE TALLY" > tallyEnd := false. > [(Delay forSeconds: 300) wait. tallyEnd := true] fork. > > "EMULATE REGULAR SQUEAK USER ACTIVITY LOOP" > [[World doOneCycle. Processor yield. tallyEnd] whileFalse] > "TALLY THE CALL STACK AT EACH SENT OF YOUR METHODS" > on: YourNotification > do: [:exc | tally tally: exc signalerContext by: 1. > exc resume]. > > "OPEN A WINDOW WITH TALLY CALL STACK RESULTS" > (StringHolder new contents: > (String streamContents: [:s | tally report: s])) > openLabel: 'YourNotification Spy Results'. > tally close. > > > > You put the code snippet in a workspace and execute it (DoIt). > Thanks to [World doOneCycle] emulation this enables you to run any > activity you like during the 300 seconds duration including interactive > and graphical activity but also running some SUnit tests cases if you > want to. > > Thanks to YourNotification Exception handling, the tally will catch each > and every send to the method(s) of interest (where you raised > YourNotification), rather than randomly analyze callStack every few > milliseconds. > > Some core or UI activity are really impossible to debug with a halt and > step by step processing in debugger, in which case this hack is usefull. > (like tracing a Font or a Morphic bug / see > http://bugs.squeak.org/view.php?id=1035 or > http://bugs.squeak.org/view.php?id=2084 for example). > > Of course, you do not catch each and every possible send of the > method(s), but only actual send you triggered by your selected activity. > It's complementary to browsing activity when polymorphism makes it > complex to track... > > You can change the 300 seconds timer at will, or end the tally manually > by executing tallyEnd := true with a doIt in the same workspace rather > than forking a timer... > > If you omit the final tally close, you can also cumulate tallies by > rearming the timer and tally block (simply doIt!). > > Though i tried to be didactic, I know this hack might be just too much > for this list, but isn't it amazingly clear and powerful what you can do > with Smalltalk in a few lines? > Just invent your own variations... > > Nicolas This is a very valuable how to get more juice of Squeak ! Very thanks , and in case you have more about tell us where or maybe add all you have into http://wiki.squeak.org/squeak/369 Edgar _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |