# Alter String base class to perform new (private methods) before returning itself when called by pri

**URL:** <https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295>\
**Category:** Ruby\
**Created:** [February 16, 2008, 7:30am UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295 "2008-02-16T07:30:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 16, 2008, 7:30am UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/1 "2008-02-16T07:30:48Z")

</div>

class String  
def summon  
puts "You summon: " + self  
end  
def summon2  
puts "You summon: " + self.gsub(‘x’,‘y’)  
end  
def to\_s  
return “Atreyu”  
end  
end

“Artax”.summon  
“Artax”.summon2

puts “Artax”.to\_s # reference 1  
puts “Artax” # reference 2

This produces…

You summon: Artax  
You summon: Artay  
Atreyu  
Artax

Now the “summon” methods indicate to me that by referencing self in  
methods added to the String class, you can alter the string from  
within itself. The question is, how can I get `puts "Artax"` to  
produce the same results as `puts "Artax"`. They are both Strings  
and, as far as I understand it, to\_s is what is used to get a String’s  
display value.

Question #1: Is there a way to references 1 and 2, supra, to do the  
same thing?

Question #2: I thought perhaps I could do the magic on the assignment  
operation. I’m not having too much luck with that, as yet.

If this is the best solution, could the responding individual please  
be so gracious as to provide example code of how to override  
assignment? I’m muddling about with my re-defined initialize  
expecting an optional argument, but I’ve not figured out how to access  
it properly.

Thanks,

Steven

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 16, 2008, 1:25pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/2 "2008-02-16T13:25:33Z")

</div>

On 16.02.2008 07:26, Steven G. Harms wrote:

> end  
> You summon: Artay  
> Atreyu  
> Artax
> 
> Now the “summon” methods indicate to me that by referencing self in  
> methods added to the String class, you can alter the string from  
> within itself.

Actually your summon methods do not alter self.

> The question is, how can I get `puts "Artax"` to  
> produce the same results as `puts "Artax"`.

??? It’s the same statement so I would expect the same output (module  
changes of the instance in between invocations).

> They are both Strings  
> and, as far as I understand it, to\_s is what is used to get a String’s  
> display value.

It’s generally not a good idea to mess with such basic classes like  
String in this way (i.e. make to\_s return something else than self).  
Since your example does not contain context it’s difficult to come up  
with appropriate suggestions. What are you _really_ trying to achieve?

> Question #1: Is there a way to references 1 and 2, supra, to do the  
> same thing?

Not sure what you mean here. Can you explain?

> Question #2: I thought perhaps I could do the magic on the assignment  
> operation. I’m not having too much luck with that, as yet.

You cannot change the semantics of assignment. You can however define  
methods that look like assignment, i.e. def foo=(x)…end. I doubt  
though that this is helpful for you in this context.

> If this is the best solution, could the responding individual please  
> be so gracious as to provide example code of how to override  
> assignment? I’m muddling about with my re-defined initialize  
> expecting an optional argument, but I’ve not figured out how to access  
> it properly.

Again, what problem are you trying to solve?

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 16, 2008, 2:37pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/3 "2008-02-16T14:37:21Z")

</div>

On Feb 16, 2008 12:29 AM, Steven G. Harms [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> class String  
> def summon  
> puts "You summon: " + self  
> end  
> def summon2  
> puts "You summon: " + self.gsub(‘x’,‘y’)  
> end

Keep in mind that these methods output what you want in irb, but  
return nil. In my irb session it looks something like this…  
irb(main):001:0\> class String  
irb(main):002:1\> def summon  
irb(main):003:2\> puts "You summon: " + self  
irb(main):004:2\> end  
irb(main):005:1\> end  
=\> nil  
irb(main):006:0\> s = “hello”.summon  
You summon: hello  
=\> nil  
irb(main):007:0\> s  
=\> nil

> This produces…
> 
> You summon: Artax  
> You summon: Artay  
> Atreyu  
> Artax
> 
> Now the “summon” methods indicate to me that by referencing self in  
> methods added to the String class, you can alter the string from  
> within itself.

Yes, this is possible.

> The question is, how can I get `puts "Artax" ` to  
> produce the same results as `puts "Artax"`. They are both Strings  
> and, as far as I understand it, to\_s is what is used to get a String’s  
> display value.
> 
> Question #1: Is there a way to references 1 and 2, supra, to do the  
> same thing?

Look at these two (using the previous code)…

puts s.to\_s  
puts(s).to\_s

> Thanks,
> 
> Steven

Todd

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 16, 2008, 2:46pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/4 "2008-02-16T14:46:09Z")

</div>

On Feb 16, 2008 7:37 AM, Todd B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Look at these two (using the previous code)…
> 
> puts s.to\_s  
> puts(s).to\_s

No, no , no!! Not using all the previous code! My bad. More “after”  
code for you (BTW, Robert’s right, you shouldn’t really mess with  
#to\_s)…

class String  
def to\_s  
“hi”  
end  
end

puts “hello”.to\_s  
puts(“hello”).to\_s

Todd

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 16, 2008, 6:15pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/5 "2008-02-16T18:15:44Z")

</div>

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 ;).

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 ).

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](http://stevengharms.com/?page_id=1159)

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.

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 ).

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?

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!

Steven

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 17, 2008, 3:05pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/6 "2008-02-17T15:05:56Z")

</div>

Robert,

Thank you for such a connsidered reply.

On Feb 17, 4:57 am, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 🙂 My Latin is very rusty nowadays but this brings back memories (our  
> first sentence in class five was “agricola arat”)… 🙂

It’s always about the farmers, isn’t it?

> > Here’s the output (at top) and code (at bottom):[stevengharms.com](http://stevengharms.com/?page_id=1159)
> 
> Where exactly? I could neither see code nor latin words on that page.

I _believe_ you can now see the code at:  
[http://stevengharms.com/improving-the-latin-command-line-verb-conjugator](http://stevengharms.com/improving-the-latin-command-line-verb-conjugator)

I just changed my ‘slug’ type and failed to understand that the  
preview was for admin-eyes-only.

> > 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.  
> I see your point on check\_macron not being optimally named, let me  
> keep the old name for purposes of this thread but I’ll act on that  
> recommendation.

> 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).  
> [code snip]

That’s sensible. I’ve never seen this Struct.new syntax so I’ll be  
eager to try it out. I think i ( perhaps cumbersomely? ) wind up  
going more-or-less along this design pattern ( now that you can see  
the code ).

> ```
> case
> 
> ```
> 
> def remove\_macron(str)  
> …  
> end  
> end
> 
> And then
> 
> voc = LatinVocabulary.new  
> voc.die = “alea”  
> voc.peasant = “agricola”

This feels very “intro to metaprogramming” - the use of the  
method\_missing method could, in principle, be used to expand the  
class. i.e.(pseudocode) “if method\_missing (:active\_present) do the  
active\_present build with macron\_sanitization routine”. This may be  
where my code goes to once I get a bit more cleaned up.

> > 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.

Heh, well I suppose I was a bit overwhelmed by the idea of open  
classes and figured that Ruby would let me saw my hand off on this  
point, if I wanted to. That said, I agree it’s probably a good thing  
that this can’t get mucked about with.

> 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).

I think I wind up doing the former

Thank you for your illuminating replies,

Steven

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 17, 2008, 5:25pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/7 "2008-02-17T17:25:57Z")

</div>

On 17.02.2008 15:00, Steven G. Harms wrote:

> Thank you for such a connsidered reply.

You’re welcome!

> On Feb 17, 4:57 am, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > 🙂 My Latin is very rusty nowadays but this brings back memories (our  
> > first sentence in class five was “agricola arat”)… 🙂
> 
> It’s always about the farmers, isn’t it?

:-))

> > > Here’s the output (at top) and code (at bottom):[stevengharms.com](http://stevengharms.com/?page_id=1159)  
> > > Where exactly? I could neither see code nor latin words on that page.
> 
> I _believe_ you can now see the code at:  
> [http://stevengharms.com/improving-the-latin-command-line-verb-conjugator](http://stevengharms.com/improving-the-latin-command-line-verb-conjugator)

I can confirm that. 🙂

Few remarks: your type checking can be simplified:

case input  
when Array  
…  
when String  
…  
else  
raise ArgumentError, “wrong type: #{input.inspect}”  
end

Same for the conjugation, for which I would introduce symbols as names  
(not “1”, “2” etc.).

Same in evaluate\_conjugation.

def evaluate\_conjugation  
case @infinitive  
when /?re$/ # what exactly should your regexp look like?  
# question mark without escaping backslash  
# is not so good  
“1” # or rather a symbol denoting the name  
when /…  
…  
else  
end  
end

> > 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).  
> > [code snip]
> 
> That’s sensible. I’ve never seen this Struct.new syntax so I’ll be  
> eager to try it out. I think i ( perhaps cumbersomely? ) wind up  
> going more-or-less along this design pattern ( now that you can see  
> the code ).

Struct.new is actually just a convenient way to create a new class with  
a set of properties that are honored during #hash, #eql? and #== so  
instances can be easily compared and used as Hash keys.

[…]

> This feels very “intro to metaprogramming” - the use of the  
> method\_missing method could, in principle, be used to expand the  
> class. i.e.(pseudocode) “if method\_missing (:active\_present) do the  
> active\_present build with macron\_sanitization routine”. This may be  
> where my code goes to once I get a bit more cleaned up.

If you know the method beforehand it is more efficient to define it  
right away.

> > 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).
> 
> I think I wind up doing the former
> 
> Thank you for your illuminating replies,

You’re welcome! I’m glad I could help.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Steven\_GSHarms](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/2bfe46/32.png) [@Steven\_GSHarms](https://www.ruby-forum.com/u/Steven_GSHarms)\
**Post date:** [February 17, 2008, 12:01pm UTC](https://www.ruby-forum.com/t/alter-string-base-class-to-perform-new-private-methods-before-returning-itself-when-called-by-pri/129295/8 "2008-02-17T12:01:07Z")

</div>

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”)… 🙂

> 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): [stevengharms.com](http://stevengharms.com/?page_id=1159)

Where exactly? I could neither see code nor latin words on that page.

> 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”

> 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
