Object methods

Hello there. :slight_smile:

Ok, I know I can do this to add a method (and a class)
to an object:

irb(main):001:0> s = "Testing!"
=> "Testing!"
irb(main):002:0> class <<s
irb(main):003:1> def says
irb(main):004:2> puts "s says:"+self
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> s.says
s says:Testing!
=> nil
irb(main):008:0> x = "Another test."
=> "Another test."
irb(main):009:0> x.says
NoMethodError: undefined method `says' for "Another
test.":String
        from (irb):9
irb(main):010:0>

My question is, dinamically, how to do that? Just like
this:

irb(main):010:0> x.class.class_eval %q(def x.says()
puts "x says:"+self end)
=> nil
irb(main):011:0> x.says
x says:Another test.

Or there is another shorter way to do that, with an
object? To build an object method with some parameters
like a string or a Proc?

Thanks! :slight_smile:

···

from :0

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
http://beam.to/taq
Usuário GNU/Linux no. 224050

Eustaquio Rangel de Oliveira J wrote:

Hello there. :slight_smile:

Ok, I know I can do this to add a method (and a class)
to an object:

irb(main):001:0> s = "Testing!"
=> "Testing!"
irb(main):002:0> class <<s
irb(main):003:1> def says
irb(main):004:2> puts "s says:"+self
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> s.says
s says:Testing!
=> nil
irb(main):008:0> x = "Another test."
=> "Another test."
irb(main):009:0> x.says
NoMethodError: undefined method `says' for "Another
test.":String
        from (irb):9
        from :0
irb(main):010:0>

My question is, dinamically, how to do that? Just like
this:

irb(main):010:0> x.class.class_eval %q(def x.says()
puts "x says:"+self end)
=> nil
irb(main):011:0> x.says
x says:Another test.

Or there is another shorter way to do that, with an
object? To build an object method with some parameters
like a string or a Proc?

I'm not sure what exactly you're after. Do you mean

class String
   def says
     print "s says: ", self, "\n"
   end
end

?

  robert

Hello, Robert!

I'm not sure what exactly you're after. Do you mean
class String
   def says
     print "s says: ", self, "\n"
   end
end
?

Not really, I want to create a new method on the
object, after it's created, but not on the class. As
the previous example of

s = "Testing"
class <<s
   def says
      print "s says: ", self, "\n"
   end
end

where it creates the method (and all that metaclass
stuff).

At this point just, just s have the "says" method, not
the class String or any other String object that was
created or will be created. Using

s.class.class_eval %q(def x.says() puts "x says:"+self
end)

have the same effect, but what I like to know if there
is another way to do that. I mean, create a method on
a specific object (on this case, just "s"), not on the
class.

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Oooooops, sorry for this. The correct example is:

s.class.class_eval %q(def s.says() puts "s says:"+self
end)

I copied the wrong part of my previous email. :-p

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
http://beam.to/taq
Usuário GNU/Linux no. 224050

Eustaquio Rangel de Oliveira J wrote:

Hello, Robert!

I'm not sure what exactly you're after. Do you mean
class String
  def says
    print "s says: ", self, "\n"
  end
end
?

Not really, I want to create a new method on the
object, after it's created, but not on the class. As
the previous example of

s = "Testing"
class <<s
   def says
      print "s says: ", self, "\n"
   end
end

where it creates the method (and all that metaclass
stuff).

At this point just, just s have the "says" method, not
the class String or any other String object that was
created or will be created. Using

s.class.class_eval %q(def x.says() puts "x says:"+self
end)

have the same effect, but what I like to know if there
is another way to do that. I mean, create a method on
a specific object (on this case, just "s"), not on the
class.

Best regards,

----------------------------
Eustáquio "TaQ" Rangel eustaquiorangel@yahoo.com
The easiest way to create, record and stream live video - Beings Usuário GNU/Linux no. 224050

Hmmm...you can use Object#extend to add the instance methods from a module. Is that what you're looking for?

How about:

   def s.says
     puts "s says: #{self}"
   end

?

David

···

On Sun, 26 Mar 2006, Eustaquio Rangel de Oliveira J wrote:

Hello, Robert!

I'm not sure what exactly you're after. Do you mean
class String
   def says
     print "s says: ", self, "\n"
   end
end
?

Not really, I want to create a new method on the
object, after it's created, but not on the class. As
the previous example of

s = "Testing"
class <<s
  def says
     print "s says: ", self, "\n"
  end
end

where it creates the method (and all that metaclass
stuff).

At this point just, just s have the "says" method, not
the class String or any other String object that was
created or will be created. Using

s.class.class_eval %q(def x.says() puts "x says:"+self
end)

have the same effect, but what I like to know if there
is another way to do that. I mean, create a method on
a specific object (on this case, just "s"), not on the
class.

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

Eustaquio Rangel de Oliveira J wrote:

Hello, Robert!

I'm not sure what exactly you're after. Do you mean
class String
   def says
     print "s says: ", self, "\n"
   end
end
?

Not really, I want to create a new method on the
object, after it's created, but not on the class. As
the previous example of

s = "Testing"
class <<s
   def says
      print "s says: ", self, "\n"
   end
end

where it creates the method (and all that metaclass
stuff).

At this point just, just s have the "says" method, not
the class String or any other String object that was
created or will be created. Using

s.class.class_eval %q(def x.says() puts "x says:"+self
end)

have the same effect,

This doesn't work for me. You define a method "say" for an instance "x" in the scope of the class. You probably want something else.

> but what I like to know if there

is another way to do that. I mean, create a method on
a specific object (on this case, just "s"), not on the
class.

def s.says
   puts "I say " + self
end

It would certainly help if you tell us what problem you are trying to solve.

Cheers

  robert

Hi, David.

How about:

   def s.says
     puts "s says: #{self}"
   end
?

Yes, this way works, but I need to make it
dinamically, for example (don't know if it's a valid
situation, just curious about) reading the code from a
string from a file. If I type the code above it's ok,
but I want to load the new methods from somewhere.

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Hi, Tim!

Hmmm...you can use Object#extend to add the instance
methods from a
module. Is that what you're looking for?

But on that way I need a previou module with the
methods. What I want is to create the methods on a
certain object, "on the air", I mean, from a string or
something like that.

The s.class.class_eval <string here> make this kind of
thing, but I was curious about some other way to do
that. :slight_smile:

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Hi Robert!

> s.class.class_eval %q(def x.says() puts "x
says:"+self
> end)
This doesn't work for me. You define a method "say"
for an instance "x"
  in the scope of the class. You probably want
something else.

I noticed that I made a mistake there and correct it
on another email few seconds after that one. Sorry
about that. My fault.

As I told on the other email, the correct thing is

s.class.class_eval %q(def s.says() puts "s says:"+self
end)

So I create a method "says" only on the object s (not
on the class String where it belongs to).

It would certainly help if you tell us what problem
you are trying to solve.

Ok, not really a problem, I was just curious about it.

Let's imagine that I need a way to create methods on
*specific objects*, not on their classes. The methods
are stored on some file or the user type it when using
the program (ok, I know the security concerns about
that :-), and I find them later using some reflection
and respond_to calls.

So at some point the user knows (again, don't know if
its a valid situation) that there are some String
objects hangin' there, s and x, and says "hey, add
this method I defined here on this text field, as a
string, to the s object, but *just to it*, not to its
class or other String objects". On this case, knowing
that I want to create the method just on s, and it's a
String, I can use

String.class_eval %q(def s.says() puts "s says:"+self
end)

to make this works, and ask for some reavaliation of
the current objects, where it will tell me that the s
object, yes, have a "says" method there.

s.respond_to?(:says)

It works this way, I was just curious if there is not
an *object method* to do that, not using the class to
make it works. But works this way because of the need
to add a virtual class to s to hold the says() method,
right?

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Eustaquio Rangel de Oliveira J <eustaquiorangel@yahoo.com> schrieb:

Let's imagine that I need a way to create methods on
*specific objects*, not on their classes. The methods
are stored on some file or the user type it when using
the program (ok, I know the security concerns about
that :-), and I find them later using some reflection
and respond_to calls.

Erm, maybe you're searching for "instance_eval"?

Patrick

···

--
'Today Is A Good Day For Someone Else To Die!'
(Feet of Clay)

Erm, maybe you're searching for "instance_eval"?

That's it!

irb(main):001:0> s = "Testing!"
=> "Testing!"
irb(main):002:0> s.instance_eval %q(def says() puts "s
says:"+self end)
=> nil
irb(main):003:0> s.says
s says:Testing!

Thanks, Patrick!

I read about instance_eval some time ago and forgot
completly about it! I knew there there was an easier
way to do that without class_eval, but ... man, what a
headache. :slight_smile:

Thanks for the help guys. :slight_smile:

Best regards,

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
http://beam.to/taq
Usuário GNU/Linux no. 224050

And of course here's how to do it with class_eval, just to make life more exciting:

(class << a; self; end).class_eval <string>

···

On Mar 26, 2006, at 11:07 AM, Eustaquio Rangel de Oliveira J wrote:

I read about instance_eval some time ago and forgot
completly about it! I knew there there was an easier
way to do that without class_eval, but ... man, what a
headache. :slight_smile:

And of course here's how to do it with class_eval,
just to make life
more exciting:
(class << a; self; end).class_eval <string>

Yes, that is almost my first example of the problem.

The point is that I forgot completely about
instance_eval, do you know those moments when you need
to use something, is sure that there is a (or other)
way to do the it but don't remember how to do it? I
knew about the <<, virtual classes, class_eval, but
forgot instance_eval. :slight_smile:

I hate this kind of "blocks" and "blanks". Maybe I
need some vacations. :slight_smile:

The good thing is that we can ask for our good friends
about that. Thanks, dudes. :slight_smile:

···

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050