Hi,
I'm working in trait aware refactorings, and I reached a point in which I have to use them so as to give them a try in real cases and see how suitable they are or see what other features should be nice to have. I'm wandering through the image looking for good candidates to apply traits. I started (and I already finished) with Magnitude and a few particular classes. Now it's time for another refactoring a little more ambitious, but not many ideas have came out of my mind so far :( Stream and Collection (I know the latter was already refactored) are good candidates, I'll start looking at them, but I was wondering if there wasn't other projects/frameworks like Seaside, Magritte, Morph? or something else, that could benefit from traits. I'm not looking to implement something with traits from scratch, I just want to take a set of classes, methods (or traits, why not) and restructure code by applying refactorings instead of doing it manually. Anyone having an idea, please let me know it. Just name a class and a couple of methods you know are spread across several classes and where you think traits would help, and I'll figure out what and how to refactor. Thanks in advance Alejandro |
You could look at the CharacterScanner and MultiCharacterScanner
hierarchies. |
On Thu, 06 Sep 2007 15:55:30 +0200, Andrew Tween wrote:
> You could look at the CharacterScanner and MultiCharacterScanner > hierarchies. May I add, copy&paste via the clipboard (for example, from an external web browser) is sometimes not the same as opening a file from Squeak's host platform and asking for contentsOfEntireFile. Example contents: - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/Geography.kif - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/People.kif /Klaus |
In reply to this post by Andrew Tween
Andrew Tween wrote:
> You could look at the CharacterScanner and MultiCharacterScanner > hierarchies. That's probably not worth it. MultiCharacterScanner was written to replace CharacterScanner, a step which simply was never completed in Squeak. Yes, you can probably use traits to squeeze out some duplicated code but if you'd seriously consider using both you wouldn't have started the duplicated hierarchy to begin with. It's entire purpose was to replace CharacterScanner in situ. If Alejandro is looking for challenges, here are two: 1) The metaclass kernel of Squeak. Yes, it is written as traits already. But that hasn't exactly improved its clarity (quite to the contrary I would argue). I'd be quite interested to see whether there is an alternative that actually improves it. 2) Morphic. How's that for a challenge :) And if that's way too big then maybe Pavel's minimal Morphic of Juan's Morphic 3.0. What I'd be curious about is whether there is a real improvement to be gained by factoring the numerous responsibilities into traits or not. Cheers, - Andreas |
In reply to this post by mrgonza78
Keep in mind that Traits are not at the same level as inheritance, for
instance. I wouldn't think of traits as a means of eliminating code duplication, even if that is how they are often sold. I would try to keep the mind set that Traits are.... traits. That is "am I working here with a new entity? (create a class) An entity that has various specializations? (create subclasses) Or am I working with a trait that many unrelated classes have? (trait)". If you use this mindset then I think you can find elegant places for traits when they are needed. If we go around looking for duplicated code and stick a trait in there we will end up with a mess. There are many ways of eliminating duplicate code, you don't need traits for this. Having said that, I would like to see what you've done with Magnitude as that is a very obvious trait in my opinion. To find a trait look for classes that seem to be inherited to the wrong place, purely to gain some interface or something. A trait could be hiding there, or it could simply be a case that needs normal traditional refactoring. The other thing I would personally keep in mind is that traits probably work best when kept small. For example, in Magnitude you basically just have equality and comparison. I would even break that up to an equality trait (for things which can be equal) and a comparison trait (for things which can be compared). If you get a trait that is as big as a class, then I would consider that a strong code smell. On 9/6/07, Alejandro Gonzalez <[hidden email]> wrote: > Hi, > I'm working in trait aware refactorings, and I reached a point in which I > have to use them so as to give them a try in real cases and see how suitable > they are or see what other features should be nice to have. > I'm wandering through the image looking for good candidates to apply > traits. I started (and I already finished) with Magnitude and a few > particular classes. Now it's time for another refactoring a little more > ambitious, but not many ideas have came out of my mind so far :( > Stream and Collection (I know the latter was already refactored) are good > candidates, I'll start looking at them, but I was wondering if there wasn't > other projects/frameworks like Seaside, Magritte, Morph? or something else, > that could benefit from traits. > I'm not looking to implement something with traits from scratch, I just > want to take a set of classes, methods (or traits, why not) and restructure > code by applying refactorings instead of doing it manually. > Anyone having an idea, please let me know it. Just name a class and a > couple of methods you know are spread across several classes and where you > think traits would help, and I'll figure out what and how to refactor. > Thanks in advance > Alejandro > > > > |
In reply to this post by Klaus D. Witzel
Klaus D. Witzel wrote:
> May I add, copy&paste via the clipboard (for example, from an external > web browser) is sometimes not the same as opening a file from Squeak's > host platform and asking for contentsOfEntireFile. Example contents: > > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/Geography.kif > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/People.kif That would likely be because the default character encoding for files (UTF-8) is different from the default encoding of your web browser (ISO-8859-1). If you change this to say, file := FileStream readOnlyFileNamed: 'People.kif'. file converter: Latin1TextConverter new. file contents. you should get the same result. Cheers, - Andreas |
Yes, I would like to reiterate again: If you want to get a success
story with traits the way to do it is not to simply cram them in somewhere and say "see! used in practice". In fact if that's all we have of traits in the end they will be seen (rightfully so) as a failure. So before using traits somewhere it should heavily be weighed if a more traditional approach wouldn't work better or even just as well. In either case I would take the traditional approach, as using traits in these cases makes it look like unneeded duplication of features. On 9/6/07, Andreas Raab <[hidden email]> wrote: > Klaus D. Witzel wrote: > > May I add, copy&paste via the clipboard (for example, from an external > > web browser) is sometimes not the same as opening a file from Squeak's > > host platform and asking for contentsOfEntireFile. Example contents: > > > > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/Geography.kif > > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/People.kif > > That would likely be because the default character encoding for files > (UTF-8) is different from the default encoding of your web browser > (ISO-8859-1). If you change this to say, > > file := FileStream readOnlyFileNamed: 'People.kif'. > file converter: Latin1TextConverter new. > file contents. > > you should get the same result. > > Cheers, > - Andreas > > |
On Thu, 06 Sep 2007 18:27:50 +0200, Jason Johnson wrote:
> Yes, I would like to reiterate again: If you want to get a success > story with traits the way to do it is not to simply cram them in > somewhere and say "see! used in practice". I'm not referring to the example I gave (and have still to check Andreas suggestion) but, If nobody tries then the opposite "not found to be usable in practice" is equally far away? > In fact if that's all we > have of traits in the end they will be seen (rightfully so) as a > failure. > > So before using traits somewhere it should heavily be weighed if a > more traditional approach wouldn't work better or even just as well. Isn't that part&parcel of what Alejandro is about to find out. > In either case I would take the traditional approach, as using traits > in these cases makes it look like unneeded duplication of features. Both cases (with, w/o) traits can only be compared if both cases exist? /Klaus > On 9/6/07, Andreas Raab <[hidden email]> wrote: >> Klaus D. Witzel wrote: >> > May I add, copy&paste via the clipboard (for example, from an external >> > web browser) is sometimes not the same as opening a file from Squeak's >> > host platform and asking for contentsOfEntireFile. Example contents: >> > >> > - >> http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/Geography.kif >> > - >> http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/People.kif >> >> That would likely be because the default character encoding for files >> (UTF-8) is different from the default encoding of your web browser >> (ISO-8859-1). If you change this to say, >> >> file := FileStream readOnlyFileNamed: 'People.kif'. >> file converter: Latin1TextConverter new. >> file contents. >> >> you should get the same result. >> >> Cheers, >> - Andreas >> >> > > |
In reply to this post by Andreas.Raab
Hi Andreas,
on Thu, 06 Sep 2007 18:11:16 +0200, you wrote: > Klaus D. Witzel wrote: >> May I add, copy&paste via the clipboard (for example, from an external >> web browser) is sometimes not the same as opening a file from Squeak's >> host platform and asking for contentsOfEntireFile. Example contents: >> - >> http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/Geography.kif >> - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/People.kif > > That would likely be because the default character encoding for files > (UTF-8) is different from the default encoding of your web browser > (ISO-8859-1). If you change this to say, > > file := FileStream readOnlyFileNamed: 'People.kif'. > file converter: Latin1TextConverter new. > file contents. > > you should get the same result. That did it. Problem solved, project in better shape now. I owe you a beer, Andreas. A traits-free one :) /Klaus > Cheers, > - Andreas > > |
In reply to this post by Jason Johnson-5
In my particular case, what I'm doing is a master thesis about trait aware refactorings. I'm not looking for the best usages of traits. My focus is on the traits aware refactorings I'm working on.
That's on one hand, on the other hand I agree that just removing code duplicated across hierarchies is not the best way of selling traits. I posted the message because I don't only want to show the result of the refactorings per se, but I also look for a good case in which traits fits well (if the effort of the refactoring doesn't get me out of my thesis). I think what I'll end doing is half and a half: I'll apply refactorings just to remove duplicated code or just for the sake of the refactorings (so I can collect result or conclusions from them) and also, I'll aply refactorings for the sake of both the refactorings and traits (so I can collect result or conclusions from the refactorings and at the same time show how good traits are). May be I was too ambitious when I named Seaside, Magritte and Morph. Looking for good traits and refactoring in those framework may take me several months and may be subject of it's own thesis (if any). Thanks for the mind set and hints, I found them very useful. Alejandro
|
How about, in addition to the traits refactorings, also looking at
alternative methods to achieve the same goals and compare and contrast them? I find it unfortunate that so far no work has been done that actually compares refactorings with traits to those done without and see what the differences and similarities are. Cheers, - Andreas mrgonza78 wrote: > In my particular case, what I'm doing is a master thesis about trait aware > refactorings. I'm not looking for the best usages of traits. My focus is on > the traits aware refactorings I'm working on. > That's on one hand, on the other hand I agree that just removing code > duplicated across hierarchies is not the best way of selling traits. > I posted the message because I don't only want to show the result of the > refactorings per se, but I also look for a good case in which traits fits > well (if the effort of the refactoring doesn't get me out of my thesis). > I think what I'll end doing is half and a half: I'll apply refactorings just > to remove duplicated code or just for the sake of the refactorings (so I can > collect result or conclusions from them) and also, I'll aply refactorings > for the sake of both the refactorings and traits (so I can collect result or > conclusions from the refactorings and at the same time show how good traits > are). > May be I was too ambitious when I named Seaside, Magritte and Morph. Looking > for good traits and refactoring in those framework may take me several > months and may be subject of it's own thesis (if any). > Thanks for the mind set and hints, I found them very useful. > Alejandro > > > Jason Johnson-5 wrote: >> Keep in mind that Traits are not at the same level as inheritance, for >> instance. I wouldn't think of traits as a means of eliminating code >> duplication, even if that is how they are often sold. I would try to >> keep the mind set that Traits are.... traits. That is "am I working >> here with a new entity? (create a class) An entity that has various >> specializations? (create subclasses) Or am I working with a trait that >> many unrelated classes have? (trait)". >> >> If you use this mindset then I think you can find elegant places for >> traits when they are needed. If we go around looking for duplicated >> code and stick a trait in there we will end up with a mess. There are >> many ways of eliminating duplicate code, you don't need traits for >> this. >> >> Having said that, I would like to see what you've done with Magnitude >> as that is a very obvious trait in my opinion. To find a trait look >> for classes that seem to be inherited to the wrong place, purely to >> gain some interface or something. A trait could be hiding there, or >> it could simply be a case that needs normal traditional refactoring. >> >> The other thing I would personally keep in mind is that traits >> probably work best when kept small. For example, in Magnitude you >> basically just have equality and comparison. I would even break that >> up to an equality trait (for things which can be equal) and a >> comparison trait (for things which can be compared). If you get a >> trait that is as big as a class, then I would consider that a strong >> code smell. >> >> On 9/6/07, Alejandro Gonzalez <[hidden email]> wrote: >>> Hi, >>> I'm working in trait aware refactorings, and I reached a point in which >>> I >>> have to use them so as to give them a try in real cases and see how >>> suitable >>> they are or see what other features should be nice to have. >>> I'm wandering through the image looking for good candidates to apply >>> traits. I started (and I already finished) with Magnitude and a few >>> particular classes. Now it's time for another refactoring a little more >>> ambitious, but not many ideas have came out of my mind so far :( >>> Stream and Collection (I know the latter was already refactored) are >>> good >>> candidates, I'll start looking at them, but I was wondering if there >>> wasn't >>> other projects/frameworks like Seaside, Magritte, Morph? or something >>> else, >>> that could benefit from traits. >>> I'm not looking to implement something with traits from scratch, I just >>> want to take a set of classes, methods (or traits, why not) and >>> restructure >>> code by applying refactorings instead of doing it manually. >>> Anyone having an idea, please let me know it. Just name a class and a >>> couple of methods you know are spread across several classes and where >>> you >>> think traits would help, and I'll figure out what and how to refactor. >>> Thanks in advance >>> Alejandro >>> >>> >>> >>> >> >> > |
Hi Andreas,
there are other guys (Claudio and Nicolas, they just sent and email about traits browser) that are doing something quite similar to what you suggest. They will re-implement the Collection hierarchy using traits and compare that model to the current Collection hierarchy to see if they got a better model/implementation using traits or not. I think that doing exactly what you suggest in this case is not easy because there is a well accepted implementation of the Collection hierarchy... we should look for another problem to apply your idea without "noise"... I keep that in mind and offer your idea to other students. Thanks! Hernan On 9/6/07, Andreas Raab <[hidden email]> wrote: How about, in addition to the traits refactorings, also looking at |
In reply to this post by Klaus D. Witzel
On 9/6/07, Klaus D. Witzel <[hidden email]> wrote:
> On Thu, 06 Sep 2007 18:27:50 +0200, Jason Johnson wrote: > > If nobody tries then the opposite "not found to be usable in practice" is > equally far away? I thought about this thing with traits that keeps coming up on my train ride home and I think I see the problem. I don't know what kind of thesis Alejandro has planned, but I have a quite radical suggestion that might make a good one. :) Framing The Situation As anyone paying attention knows, Andreas is probably the loudest voice challenging Traits with the hard questions/comments, and I am one of the louder people (in general but also) defending it. He comes with things like "it is basically MI again" and "it makes things more complex then it solves", and I answer with my sole defense: it makes sense for Magnitude. But does it? Of course in Haskell it's beautiful, it makes sense and "just fits". But Haskell isn't an OO language. In Haskell most of the code you write wont be overriding anything or using anything remotely resembling an object. So when you *do* actually make a type class it's not too much to ask to put in all the "deriving(Eq, Ord, .." every time because you just don't do it that much. But in Smalltalk *all you do is objects*. So using my example of Magnitude, how exactly would that work? From an entity design, it's a no brainer that equality is a trait and comparability is a trait. But once you have those 2 traits, how do you use them? (1) You could use them in Object so that all objects get the benefit, but if then why bother with the traits? Just leave it as object methods. (2) You could create an object at a high level that uses them, lets call it... Magnitude for example. Then objects that implement these traits can inherit from it and those that don't can inherit elsewhere. But this is where we are today. (3) Lastly, you could just have every single (base) class in the image use the traits that apply to it explicitly. Now that's a lot of typing. We're not in Haskell where a big project may have 10 classes total. So it would appear that due to the single inheritance, OO nature of Smalltalk and the fact that Traits are not stand alone entities themselves, there is no good way to actually use them despite their theoretical practicality. The Solution? Or maybe we have just been thinking too small. Perhaps the way to think of Traits in Squeak is as first class object protocols (or interfaces). Perhaps thinking of Traits as something that comes up every once in a while (and appear to not work even in that case) is the wrong way to go. Perhaps we should decide to put them everywhere and completely change our browser to support this radically different way of writing Smalltalk code. Suicide mission My suggestion would be that who ever wants to make a thesis download a stock Squeak image and make a forked "Traits" image to test out this experiment. In this image Equality would be a trait, Ordinality would be a trait, the "block protocol" would be a trait, being able to display yourself on a web page would be a trait. Because Traits would just be a first class protocol. But this is a different way to program. Now you probably select a class that inherits from the right place, change the name after "subclass: ", hit accept and you're off. Now you would also be dropping in capabilities (traits) to your new class to do most of the work. You would get lots of behavior from these first class protocols, but you would also have to define some of them yourself (a Trait will be in some cases just a "contract" that you will implement those methods). And the tools would have to change. We've all browsed Object I'm sure. And people mention how awful and crowded that interface is. We have categories for the methods and that helps a lot. But I wonder how many protocols are covered by object? A protocol can span many categories. Imagine if nearly all those methods moved out of object and into a trait for all those protocols. Some of those traits would just have to be used by Object anyway because it ends up answering the message. But perhaps lots of them would not, but would be traits that virtually all classes use (e.g. Equal). How many methods are in Object, not because it will receive them, but because it's the only connecting point for the classes that need them? Clearly with a new idea of defining classes, the tools would have to show this. The Traits or Protocols are now part of the documentation of the class. The browser should make you be able to glance at a class and quickly determine all of it's capabilities (maybe color code Traits that came in via inheritance). And we would need "capability templates" as well. I wouldn't want to spend 20 minutes dragging traits onto my new class every time I make one. Conclusion This email may sound pretty radical. It does to me anyway. But at this point I think such an experiment is the only way we will ever answer the question of if Traits can work or not. I think if we keep trying to piece-mail them in they are just going to look worse and worse. They will just continue to appear as a solution looking for a problem, yet another way to do things instead something actually ground breaking. If you make this fork and do these drastic changes nothing may come of it. We may find out that it wasn't a good idea after all. Or maybe, just maybe, you'll change the way we Smalltalk. But without this kind of change I no longer see a way that Traits can be anything other then what Andreas said from the beginning: MI. |
In reply to this post by hernan.wilkinson
Hernan Wilkinson wrote:
> Hi Andreas, > there are other guys (Claudio and Nicolas, they just sent and email > about traits browser) that are doing something quite similar to what you > suggest. > They will re-implement the Collection hierarchy using traits and > compare that model to the current Collection hierarchy to see if they > got a better model/implementation using traits or not. But this isn't a particularly valid comparison. If you want to find out about the value of traits you can't compare a subsystem that is being used in production and that has all kinds of legacy issues with one that doesn't have to deal with such issues. What you are comparing then is: Is a subsystem which can be implemented free of constraints superior to one that has to accommodate all sorts of constraints and legacy issues? I can tell you the answer to that question without running the experiment. And it has nothing to do with traits. So either you need to run the experiment within the same constraints that exist already (in which case you should do an in situ reimplementation of the collection hierarchy with the requirement of keeping the system running while doing it) or you need to implement both parts free of the constraints of the current system. Which are both fine options btw. > I think that doing exactly what you suggest in this case is not easy > because there is a well accepted implementation of the Collection > hierarchy... we should look for another problem to apply your idea > without "noise"... I keep that in mind and offer your idea to other > students. I think it is *very* easy to do what I proposed as long as you are clear what your goals for the refactorings are other than "use traits". If your goal is, for example, "minimize code duplication" it's clear how to do this without traits. If it is "minimize number of entities", it's clear, too. So is "restructure into more useful/generalized entities" or "unify the interfaces". As long as you are clear on what goals you're actually trying to achieve it's pretty clear how to achieve these goals with or without traits. Cheers, - Andreas |
Hi Andreas,
thank you for your comments. I agree with you in most of them. It may not be a good comparison although we are going to re implement the collection hierarchy first and the refactor it with traits. At the same time it will allow us to gain experience with traits and "measure" if it is a good tool or not. Here is a copy of the process we will follow (I sent it in other mail): > 1) Take a concrete class of the Collection hierarchy, for example OrderedCollection > 2) Create a new class (ie. XOrderedCollection) with Object as super class > 3) Take a message of the ANSI Smalltalk of the selected class (OrderedCollection) > 4) Write a test, make it work with the selected class (OrderedCollection) > 5) Make the test written in 4) work with the class created in steep 2. ( XOrderedCollection) > 6) Repeat 3,4 and 5 until all messages of the selected class (OrderedCollection) are implemented in the other class (XOrderedCollection) > 7) Select another concrete class from the Collection hierarchy (for example Array) and repeat steps from 2 to 6. > 8) Repeat steep 7 until there are enough new implementations to infer traits. > 9) Refactor the new classes into traits... and play with the model until we feel comfortable with the result. > > To put a limit in the project, they are going to implement just the ANSI Collection hierarchy >(remember that it is a master thesis...) > We thought that doing it this way the new implementation is not going to be "guided" by the >old one, we will just keep the concrete classes names but not the hierarchy necessarily... > > Please, feel free to let us know what you thing about this process, if you have other ideas, >etc. Bye, Hernan. On 9/6/07, Andreas Raab <[hidden email]> wrote: Hernan Wilkinson wrote: |
In reply to this post by Andreas.Raab
On Thu, 06 Sep 2007 08:59:47 -0700, Andreas Raab <[hidden email]>
wrote: > 2) Morphic. How's that for a challenge :) And if that's way too big then > maybe Pavel's minimal Morphic of Juan's Morphic 3.0. What I'd be curious > about is whether there is a real improvement to be gained by factoring > the numerous responsibilities into traits or not. +1 |
In reply to this post by Andreas.Raab
hi andreas
what is the difference between a CharacterScanner and a multiCharacterScanner? I imagine that this is not just scanning more than one character so what was the plan? Stef On 6 sept. 07, at 17:59, Andreas Raab wrote: > Andrew Tween wrote: >> You could look at the CharacterScanner and MultiCharacterScanner >> hierarchies. > > That's probably not worth it. MultiCharacterScanner was written to > replace CharacterScanner, a step which simply was never completed > in Squeak. Yes, you can probably use traits to squeeze out some > duplicated code but if you'd seriously consider using both you > wouldn't have started the duplicated hierarchy to begin with. It's > entire purpose was to replace CharacterScanner in situ. > > If Alejandro is looking for challenges, here are two: > 1) The metaclass kernel of Squeak. Yes, it is written as traits > already. But that hasn't exactly improved its clarity (quite to the > contrary I would argue). I'd be quite interested to see whether > there is an alternative that actually improves it. > 2) Morphic. How's that for a challenge :) And if that's way too big > then maybe Pavel's minimal Morphic of Juan's Morphic 3.0. What I'd > be curious about is whether there is a real improvement to be > gained by factoring the numerous responsibilities into traits or not. > > Cheers, > - Andreas > > |
In reply to this post by Klaus D. Witzel
+ 1
Having traits is like having middle abstractions that we can reuse. So having them and learning from the case studies is important. Stef On 6 sept. 07, at 18:51, Klaus D. Witzel wrote: > On Thu, 06 Sep 2007 18:27:50 +0200, Jason Johnson wrote: > >> Yes, I would like to reiterate again: If you want to get a success >> story with traits the way to do it is not to simply cram them in >> somewhere and say "see! used in practice". > > I'm not referring to the example I gave (and have still to check > Andreas suggestion) but, > > If nobody tries then the opposite "not found to be usable in > practice" is equally far away? > >> In fact if that's all we >> have of traits in the end they will be seen (rightfully so) as a >> failure. >> >> So before using traits somewhere it should heavily be weighed if a >> more traditional approach wouldn't work better or even just as well. > > Isn't that part&parcel of what Alejandro is about to find out. > >> In either case I would take the traditional approach, as using traits >> in these cases makes it look like unneeded duplication of features. > > Both cases (with, w/o) traits can only be compared if both cases > exist? > > /Klaus > >> On 9/6/07, Andreas Raab <[hidden email]> wrote: >>> Klaus D. Witzel wrote: >>> > May I add, copy&paste via the clipboard (for example, from an >>> external >>> > web browser) is sometimes not the same as opening a file from >>> Squeak's >>> > host platform and asking for contentsOfEntireFile. Example >>> contents: >>> > >>> > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/ >>> Geography.kif >>> > - http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/KBs/ >>> People.kif >>> >>> That would likely be because the default character encoding for >>> files >>> (UTF-8) is different from the default encoding of your web browser >>> (ISO-8859-1). If you change this to say, >>> >>> file := FileStream readOnlyFileNamed: 'People.kif'. >>> file converter: Latin1TextConverter new. >>> file contents. >>> >>> you should get the same result. >>> >>> Cheers, >>> - Andreas >>> >>> >> >> > > > > |
Free forum by Nabble | Edit this page |