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

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

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

On Feb 16, 2008 12:29 AM, Steven G. Harms [email protected]
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

On Feb 16, 2008 7:37 AM, Todd B. [email protected] 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

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

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

Robert,

Thank you for such a connsidered reply.

On Feb 17, 4:57 am, Robert K. [email protected] wrote:

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

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

Here’s the output (at top) and code (at bottom):stevengharms.com

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

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

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. [email protected] wrote:

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

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

:-))

Here’s the output (at top) and code (at bottom):stevengharms.com
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

I can confirm that. :slight_smile:

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

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

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

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

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

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