Object methods

  • Thread starter Eustaquio Rangel de Oliveira J
  • Start date
E

Eustaquio Rangel de Oliveira J

Hello there. :)

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

irb(main):001:0> s =3D "Testing!"
=3D> "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
=3D> nil
irb(main):007:0> s.says
s says:Testing!
=3D> nil
irb(main):008:0> x =3D "Another test."
=3D> "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>=20

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)
=3D> 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! :)
 
R

Robert Klemme

Eustaquio said:
Hello there. :)

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
 
E

Eustaquio Rangel de Oliveira J

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 =3D "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=20

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,
 
E

Eustaquio Rangel de Oliveira J

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,
 
D

dblack

Hello, Robert!


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.

How about:

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

?


David

--
David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
 
R

Robert Klemme

Eustaquio said:
Hello, Robert!


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
 
E

Eustaquio Rangel de Oliveira J

Hi, David.
How about:
=20
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,
 
E

Eustaquio Rangel de Oliveira J

Hi Robert!
This doesn't work for me. You define a method "say"
for an instance "x"=20
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.=20

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,
 
P

Patrick Hof

--O5XBE6gyVG5Rl6Rj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Eustaquio Rangel de Oliveira J said:
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.=20

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

Patrick

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

--O5XBE6gyVG5Rl6Rj
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD4DBQFEJrgbfpK5yKGUrIURAlygAJdXo+lmqz8S9Z16uQxDaJw0cHOyAJ0Uv8eC
b4+GoWaDFr74SZMV2GLthQ==
=R0WQ
-----END PGP SIGNATURE-----

--O5XBE6gyVG5Rl6Rj--
 
E

Eustaquio Rangel de Oliveira J

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

That's it!

irb(main):001:0> s =3D "Testing!"
=3D> "Testing!"
irb(main):002:0> s.instance_eval %q(def says() puts "s
says:"+self end)
=3D> 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. :)

Thanks for the help guys. :)

Best regards,
 
L

Logan Capaldo

--Apple-Mail-7--247799306
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed


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

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>


--Apple-Mail-7--247799306--
 
E

Eustaquio Rangel de Oliveira J

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

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

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

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

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
arinsharma
Top