From: Robert Klemme Date: 2008-02-17T20:00:06+09:00 Subject: Re: Alter String base class to perform new (private methods) before returning itself when called by print statements On 16.02.2008 18:10, Steven G. Harms wrote: > Robert, Todd, et. al., > > I apologize if my first post was missing some of the larger context, I > didn't want to have to give too much information about the problem > domain lest that deter replies ;). No problem at all. Sometimes it's hard to see where one should draw the line between too much and too few information to help people understand what's going on. > The code I'm working on is used for storing Strings which contain > conjugations of Latin verbs ( I mean, people who lived near the > Mediterranean, not people south of the Rio Grande ). :-) My Latin is very rusty nowadays but this brings back memories (our first sentence in class five was "agricola arat")... :-) > Classical Latin words contain macrons on certain vowels ( the long bar > that signifies a "long" sound ). When following conjugation rules > occasionally the "macron-ized" character needs to be "shortened" and > the macron thus removed. Thus, for example "they love" is the stem of > the infinitive remove_ending("am\={a}re") + "nt" (I'm using LaTeX > style macron representation). > > The rules dictate that you should chop off the "re" and add the "nt", > thus giving you "am\={a}nt". > > BUT here's the rule, a macronized vowel before 'nt' or 'nd' anywhere > in the string must be shortened, thus the word is *actually* "amant". > There are other conditions that shorten a macron (comes before another > vowel, etc.). > > Here's the output (at top) and code (at bottom): http://stevengharms.com/?page_id=1159 Where exactly? I could neither see code nor latin words on that page. > While I have the code that produces the "right" output, I'm trying to > refactor the code to be more Ruby-like, cleaner, and more organized. > So the code that I link to here is still functional, but not final > draft! > > As it is currently, you enter a verb characterization from the CLI, a > Verb.new object is created with that string as the input. Those > pieces are broken up and you have a Verb object. You can then issue: > > demo_verb=Verb.new( verb characterization string ) > puts demo_verb.active_present > > In 'active_present" 6 strings are created and returned in an array. > Each of these strings are passed to a "check_macron" routine which > removes macrons where needed. Personally I find this naming a bit unfortunate: checking is usually a read only operation while you are actually manipulating something. > Point #1 ( Original Question, effectively) > > My idea was "Well, what if *every* string, in the duration of this > program, knows to check_macron itself at time of assignment OR at time > of being used for output" -- my idea being to "smarten" up String so > that I didn't have to go around invoking check_macron all over the > place. Further, I wouldn't have to change my ( heavy! ) use of the > String assignment idioms ( heavily used ). That's double "heavy" - man this must be really heavy. :-) I can see where your motivation comes from. Generally I'd opt for not putting this into class String because it is too specialized (i.e functionality that does make sense in context of your application only). One possible solution that might not too bad from your point of view: add a class and define a conversion method, e.g. LatinString = Struct.new :string do def remove_macron ... end def to_s # for printing... end end class String def to_latin LatinString.new self end end now you can do die = "alea".to_latin Another alternative (modifying assignment) could be this: class LatinVocabulary def initialize @vars = {} end def method_missing(sym, *args, &b) name = sym.to_s case when /^(.*)=$/ =~ name && args.length == 1 # assignment @vars[$1] = remove_macron(args.first) when args.empty? && @vars.has_key? name # getter @vars[name] else super end end def remove_macron(str) ... end end And then voc = LatinVocabulary.new voc.die = "alea" voc.peasant = "agricola" > Point #2: > > I was against the idea of subclassing String because, as i understand > it, my assignments would take the look of: > > aLatinString = LatinString.new("something") > > instead of the very short and pleasant: > > aRegularString = "razzle" > > Perhaps I am mistaken in this? No, you are not. How should the interpreter know that "..." suddenly creates a LatinString and not a String? This is really hard coded into the language. And it's good that way because otherwise all sorts of nasty things could happen if anybody could change this. > Well, so that's the full story, likely full of a lot of extra details, > but hopefully you will make it through and be able to guide me to more > Ruby like constructions! I am still a bit unsure about when those conversions need to be done because I did not find the code where you indicated. From what you write method Verb#active_present generates this list you mentioned. Now, should this list be a list of plain Strings or do you need LatinStrings to be returned, i.e. does the result of this method call have to be modified already or do you need to be able to do it later? If the former, then you can apply the conversion in Verb#active_present, if the latter you can return a LatinString (as shown above). But generally, if you need a String with particular properties, create your own class for this. There are enough options to make handling and printing of anything as convenient as printing Strings. My 0.03EUR... Kind regards robert