irb and ruby

D

Daniel Schüle

Hello all,

I am reading this page
http://www.rubyist.net/~slagell/ruby/accesscontrol.html
especially the "fish".square example

I am puzzled by different behaviours of ruby itself and the irb

irb(main):101:0> def square x
irb(main):102:1> x*x
irb(main):103:1> end
=> nil
irb(main):105:0> [].square 12
=> 144
irb(main):106:0> "fish".square 12
=> 144
irb(main):112:0> "fish".public_methods.grep /square/
=> ["square"]
irb(main):113:0> "fish".private_methods.grep /square/
=> []

I can square my fishes and arrays ;)
but a ruby program

#!/usr/bin/env ruby
def square x
x*x
end

puts square 10
#puts "fish".square # error, cant square fishes
puts Object.private_methods.grep /square/ # yes it's there
puts Object.public_methods.grep /square/ # nope


as you can see, irb makes methods public and ruby private
what rationale is behind this behaviour?
is this something that will be "fixed" in future
or is deliberately dicision/feature

Regards, Daniel
 
J

J. Merrill

uval said:
Hello all,

I am reading this page
http://www.rubyist.net/~slagell/ruby/accesscontrol.html
especially the "fish".square example

I am puzzled by different behaviours of ruby itself and the irb

irb(main):101:0> def square x
irb(main):102:1> x*x
irb(main):103:1> end
=> nil
irb(main):105:0> [].square 12
=> 144
irb(main):106:0> "fish".square 12
=> 144
irb(main):112:0> "fish".public_methods.grep /square/
=> ["square"]
irb(main):113:0> "fish".private_methods.grep /square/
=> []

I can square my fishes and arrays ;)
but a ruby program

#!/usr/bin/env ruby
def square x
x*x
end

puts square 10
#puts "fish".square # error, cant square fishes
puts Object.private_methods.grep /square/ # yes it's there
puts Object.public_methods.grep /square/ # nope


as you can see, irb makes methods public and ruby private
what rationale is behind this behaviour?
is this something that will be "fixed" in future
or is deliberately dicision/feature

Regards, Daniel

What's going on is that when you use irb, you are inside a class called
"main"; so when you "def square ..." you have really created an instance
method main#square. In pure ruby, your "def square ..." creates a
top-level method.

I do not off the cuff understand why that changes things the way you're
seeing, but I think it means that, particularly when using ruby (vs
irb), you should only "def" inside an explicit class.
 
D

David A. Black

Hi --

uval said:
Hello all,

I am reading this page
http://www.rubyist.net/~slagell/ruby/accesscontrol.html
especially the "fish".square example

I am puzzled by different behaviours of ruby itself and the irb

irb(main):101:0> def square x
irb(main):102:1> x*x
irb(main):103:1> end
=> nil
irb(main):105:0> [].square 12
=> 144
irb(main):106:0> "fish".square 12
=> 144
irb(main):112:0> "fish".public_methods.grep /square/
=> ["square"]
irb(main):113:0> "fish".private_methods.grep /square/
=> []

I can square my fishes and arrays ;)
but a ruby program

#!/usr/bin/env ruby
def square x
x*x
end

puts square 10
#puts "fish".square # error, cant square fishes
puts Object.private_methods.grep /square/ # yes it's there
puts Object.public_methods.grep /square/ # nope


as you can see, irb makes methods public and ruby private
what rationale is behind this behaviour?
is this something that will be "fixed" in future
or is deliberately dicision/feature

Regards, Daniel

What's going on is that when you use irb, you are inside a class called
"main"; so when you "def square ..." you have really created an instance
method main#square. In pure ruby, your "def square ..." creates a
top-level method.

main isn't a class:

irb(main):021:0> self
=> main
irb(main):022:0> self.class
=> Object

It's a default object, a sort of backstop. Also, it's not
irb-specific:

$ ruby -e 'p self; p self.class'
main
Object
I do not off the cuff understand why that changes things the way
you're seeing, but I think it means that, particularly when using
ruby (vs irb), you should only "def" inside an explicit class.

I wouldn't say that. There's nothing wrong with creating top-level
methods in Ruby scripts or in irb, if that's the scope you need them
in.

I'm not sure why irb doesn't make top-level methods private, but I
think that's the only difference (in this area) between irb and Ruby.


David
 
T

ts

D> I'm not sure why irb doesn't make top-level methods private, but I
D> think that's the only difference (in this area) between irb and Ruby.

You can change its context

moulon% irb --context-mode 0
irb(main):001:0> def aa() 1+1; end
=> nil
irb(main):002:0> aa
=> 2
irb(main):003:0> self.aa
NoMethodError: private method `aa' called for main:Object
from (irb):3
from /usr/lib/ruby/1.8/irb/workspace.rb:27
from :0
irb(main):004:0>
moulon%


Guy Decoux
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top