Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > What's the difference between send and instance_eval?

Reply
Thread Tools

What's the difference between send and instance_eval?

 
 
michele
Guest
Posts: n/a
 
      10-23-2006
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.

 
Reply With Quote
 
 
 
 
Tim Pease
Guest
Posts: n/a
 
      10-23-2006
On 10/23/06, michele <> wrote:
> 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.
>


send can only be used to execute existing methods on objects.

instance_eval allows you to do much more -- i.e. adding instance
variables, tinkering with private methods, etc

ary = %w( 1 2 3 4 )

ary.send :length #=> 4

ary.instance_eval do
@length = self.length
end

ary.instance_variable_get :@length #=> 4


It's a dumb example, but it should convery the differences.

Blessings,
TwP

 
Reply With Quote
 
 
 
 
michele
Guest
Posts: n/a
 
      10-24-2006

So there is no need for "send"?

Thanks


On Oct 24, 12:54 am, "Tim Pease" <tim.pe...@gmail.com> wrote:
> On 10/23/06, michele <michelemen...@gmail.com> wrote:
>
> > 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.send can only be used to execute existing methods on objects.

>
> instance_eval allows you to do much more -- i.e. adding instance
> variables, tinkering with private methods, etc
>
> ary = %w( 1 2 3 4 )
>
> ary.send :length #=> 4
>
> ary.instance_eval do
> @length = self.length
> end
>
> ary.instance_variable_get :@length #=> 4
>
> It's a dumb example, but it should convery the differences.
>
> Blessings,
> TwP


 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      10-24-2006
michele wrote:
> So there is no need for "send"?


One use of #send:

a=[]
@x=3
a.send :<<, @x
p a

@x=4
a.instance_eval { self << @x }
p a

__END__

Output:

[3]
[3, nil]

This is because @x is in a different scope inside the instance_eval block.

Another case, showing the real point of #send:

msg = :reverse
a = [1,2,3]
b = a.send msg
p b

__END__

Output:

[3, 2, 1]

There's no easy equivalent with #instance_eval and blocks (you could
mess with strings, though).

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

 
Reply With Quote
 
Tim Pease
Guest
Posts: n/a
 
      10-24-2006
On 10/24/06, michele <> wrote:
>
> So there is no need for "send"?
>
> Thanks
>


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.

http://www.oreillynet.com/ruby/blog/..._is_a_dsl.html
http://www.artima.com/rubycs/articles/ruby_as_dsl.html

 
Reply With Quote
 
Tomasz Wegrzanowski
Guest
Posts: n/a
 
      10-24-2006
On 10/24/06, michele <> wrote:
>
> So there is no need for "send"?


But there obviously is - method in send doesn't have to be a constant.

# A delegator
def method_missing(m, args, &blk)
@obj.send(m, args, &blk)
end

Now try that with instance_eval

--
Tomasz Wegrzanowski [ http://t-a-w.blogspot.com/ ]

 
Reply With Quote
 
Wilson Bilkovich
Guest
Posts: n/a
 
      10-25-2006
On 10/24/06, Tomasz Wegrzanowski <> wrote:
> On 10/24/06, michele <> wrote:
> >
> > So there is no need for "send"?

>
> But there obviously is - method in send doesn't have to be a constant.
>
> # A delegator
> def method_missing(m, args, &blk)
> @obj.send(m, args, &blk)
> end
>
> Now try that with instance_eval


def method_missing(m, args, &block)
@obj.instance_eval { self.send(m, args, &block) }
end

Heh.

 
Reply With Quote
 
michele
Guest
Posts: n/a
 
      10-26-2006
This works:

msg = :reverse
a = [1,2,3]
a.instance_eval(msg.to_s)


On Oct 24, 6:53 pm, Joel VanderWerf <v...@path.berkeley.edu> wrote:
> michele wrote:
> > So there is no need for "send"?One use of #send:

>
> a=[]
> @x=3
> a.send :<<, @x
> p a
>
> @x=4
> a.instance_eval{ self << @x }
> p a
>
> __END__
>
> Output:
>
> [3]
> [3, nil]
>
> This is because @x is in a different scope inside theinstance_evalblock.
>
> Another case, showing the real point of #send:
>
> msg = :reverse
> a = [1,2,3]
> b = a.send msg
> p b
>
> __END__
>
> Output:
>
> [3, 2, 1]
>
> There's no easy equivalent with #instance_evaland blocks (you could
> mess with strings, though).
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      10-26-2006

Putting the comments in order...

> Joel VanderWerf wrote:
>> Another case, showing the real point of #send:
>>
>> msg = :reverse
>> a = [1,2,3]
>> b = a.send msg
>> p b
>>
>> __END__
>>
>> Output:
>>
>> [3, 2, 1]
>>
>> 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.)

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      10-26-2006
On 10/26/06, Joel VanderWerf <> wrote:

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


except that instance_eval can take a block in lieu of a string:

a.instance_eval {concat [1,2,3,4,5,6,IO,String,Kernel, h]}
=> [1, 2, 3, 1, 2, 3, 4, 5, 6, IO, String, Kernel, {1=>2}]

Not that I think that send should be eliminated, both methods are
useful. Horses for courses.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: what’s the difference between socket.send() and socket.sendall() ? Philipp Hagemeister Python 0 01-08-2013 12:42 PM
Re: what¢s the difference between socket.send()and socket.sendall() ? Steven D'Aprano Python 1 01-07-2013 03:54 PM
Re: what’s the difference between socket.send() and socket.sendall() ? Thomas Rachel Python 0 01-07-2013 01:17 PM
Difference between bin and obj directories and difference between project references and dll references jakk ASP .Net 4 03-22-2005 09:23 PM
Exact difference between 'const char *' and 'char *', also diff between 'const' and 'static' Santa C Programming 1 07-17-2003 02:10 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57