What’s the difference between send and instance_eval (except the
obvious syntax)?
I’ve been trying to figure out why Ruby has them both. It seems you can
use them intechangeably, at least in the cases I’ve found and tested
(so the question is if there is a case where can’t change one for the
other).
Sorry if this has been answered already. I really tried to find the
answers in my Ruby and Rails books and on the Internet before posting
the question here.
Actually, I use send quite often – more so than instance_eval. When I
write unit tests, I use send all the time to call the private methods
of the objects I’m testing.
I use instance_eval when I’m doing things with domain specific languages
(DSLs).
Both are equally useful – it’s just a matter of learning when to use
which one.
Oh, and no need to apologize for asking questions. The people here are
quite friendly.
Blessings,
TwP
By the way, here are two good articles about DSLs … one is theory,
the other is practice.
To make the instance_eval work here, you would have to find a way to
useful. Horses for courses.
And I’m starting to beat a dead horse here, but using a block leads you
to scoping issues. (What if the hash were @h or a method call instead of
h? You can always use an temporary local var to avoid the issue.)
There’s no easy equivalent with #instance_evaland blocks (you could
mess with strings, though).
michele wrote:
This works:
msg = :reverse
a = [1,2,3]
a.instance_eval(msg.to_s)
That’s true, but only because I chose a bad example. Here’s a better
one:
h = {1=>2}
msg = [:concat, [4, 5, 6, IO, String, Kernel, h]]
a = [1,2,3]
p a.send(*msg) # ==> [1, 2, 3, 4, 5, 6, IO, String, Kernel, {1=>2}]
p a.instance_eval(msg.to_s) # ==> NameError
To make the instance_eval work here, you would have to find a way to
turn the argument array into a string that, when eval-ed, is that same
array. (It’s possible, but painful, and you lose the identity of the
hash h.)
I may not understand it well, but I don’t like it. The two methods are
so similar that the only way to figure out the difference is to find
cases that will make it hard or impossible to use one of them. It
should be easy to choose which method to use, not hard to figure out
which one not to use. They are also conceptually different. An object
can either call a method (most common lingo among Java, C, etc) or you
can send it a message (Smalltalk), but what does “eval” mean? Ruby uses
all three (call, send and eval) which may be good (I don’t know why,
but maybe if you like to study computer languages), but if I don’t use
these methods every day, I will have to think hard every time I need
one of them.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.