The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Send my love to Ruby

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Brian Ford

Posts: 153
Nickname: brixen
Registered: Dec, 2005

Brian Ford is Rails developer with PLANET ARGON.
Send my love to Ruby Posted: Sep 19, 2007 6:14 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Brian Ford.
Original Post: Send my love to Ruby
Feed Title: def euler(x); cos(x) + i*sin(x); end
Feed URL: http://feeds.feedburner.com/defeulerxcosxisinxend
Feed Description: euler(PI) # => -1
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Brian Ford
Latest Posts From def euler(x); cos(x) + i*sin(x); end

Advertisement

Over at the Rubinius project, in between hatching plots to take over the world, we fit in some time for recreation. For example, we’ve got this masochistic interest in writing RSpec compatible specs for the Ruby core library. One of the challenges there is the large number of aliased methods that Ruby has. Using RSpec’s shared behaviors as an example, I’ve created a flavor of shared behaviors in our mini_rspec implementation. As the code below shows, this makes it straightforward to spec all these aliases.


hash_store = shared "Hash#store" do |cmd|
  describe "Hash##{cmd}" do
    it "associates the key with the value and return the value" do
      h = { :a => 1 }
      (h.send(cmd, :b, 2).should == 2
      h.should == {:b=>2, :a=>1}
    end

    it "duplicates and freezes string keys" do
      key = "foo" 
      h = {}
      h.send(cmd, key, 0)
      key << "bar" 

      h.should == { "foo" => 0 }
      h.keys[0].frozen?.should == true
    end

    it "duplicates string keys using dup semantics" do
      # dup doesn't copy singleton methods
      key = "foo" 
      def key.reverse() "bar" end
      h = {}
      h.send(cmd, key, 0)

      h.keys[0].reverse.should == "oof" 
    end  

    it "raises TypeError if called on a frozen instance" do
      should_raise(TypeError) { hash.send(cmd, 1, 2) }
    end
  end
end

describe "Hash#[]=" do
  it_behaves_like(hash_store, :[]=)
end

The very cool thing about this is how useful Ruby’s send method is. And in Rubinius, it gets even cooler. First, some code:


class Apple
  def seed
  end
end

a = Apple.new

a.send :seed
a.__send__ :seed

Now, using the very nice describe facility of the Rubinius compiler, we can see something interesting:


$ shotgun/rubinius describe send.rb
Path: send.rb
Size: 79 bytes

Sexp:
  [:block, 
  [:newline, 1, "(eval)", 
    [:class, [:colon2, :Apple], nil, 
      [:scope, 
        [:newline, 2, "(eval)", set_local_fp 1 ; local a

---- snip ----

pop
#line 8
push_literal 1
get_local_fp 1 ; local a
send send 1
pop
#line 9
get_local_fp 1 ; local a
push nil
push_literal 2
dup
is_symbol
git send_lbl1
send to_sym 0
send_lbl1:
push 0
set_args
send_off_stack
pop
push true
ret

---- snip ----

I’ve truncated that output, but feel free to run this at home. (There’s no long lasting side effects other than an itching desire to contribute to the Rubinius project.) If you correlate the assembly with the line numbers in the source, you’ll notice that the two sends are not turning out to be the same. That’s right. We have a special, and fast, __send__ operation.

The #send method is a highly useful bit of Ruby. Unfortunately, there’s some concern that using it can hurt performance. Well, with Rubinius you can have your send and use it, too.

Read: Send my love to Ruby

Topic: Tweets on 2007-09-17 Previous Topic   Next Topic Topic: Oracle annoyance of the day

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use