Have I been staring at the screen too long?

$ irb

r = [1…99, 100…199]
=> [1…99, 100…199]
xs = r.local_methods
=> [:, :, :, :-, :, :=>, :[], :[], :all?, :any?, :assoc, :at, :clear,
:collect, :collect!, :combination, :compact, :compact!, :concat, :count,
:cycle, :delete, :delete_at, :delete_if, :detect, :drop, :drop_while,
:each, :each_cons, :each_index, :each_slice, :each_with_index,
:each_with_object, :empty?, :entries, :fetch, :fill, :find, :find_all,
:find_index, :first, :flatten, :flatten!, :fold, :grep, :group_by,
:include?, :index, :inject, :insert, :join, :last, :length, :map, :map!,
:max, :max_by, :member?, :min, :min_by, :minmax, :minmax_by, :none?,
:one?, :pack, :partition, :permutation, :pop, :product, :push, :rassoc,
:reduce, :reject, :reject!, :replace, :reverse, :reverse!,
:reverse_each, :rindex, :sample, :select, :shift, :shuffle, :shuffle!,
:size, :slice, :slice!, :sort, :sort!, :sort_by, :take, :take_while,
:to_a, :to_ary, :transpose, :uniq, :uniq!, :unshift, :values_at, :zip,
:]
load ‘extensions/Array.rb’
=> true
r.local_methods - xs
=> [:rand]

This is extensions/Array.rb

class Array

def index_in_range( n )
self.each_with_index do |x, i|
return i if x === n
end
return nil
end

end

It did have a rand function in there, but I removed it because it was
being loaded but the index_in_range wasn’t. I’ve no idea how the rand
function is still getting added if it’s not defined in the file.

Any help is more than appreciated, it’s needed for my continued sanity
(which was already at question)

Regards,
Iain

David M. wrote:

Apparently, the core Array class has a private ‘rand’ method?

That’ll be Kernel#rand I expect.

irb(main):001:0> rand(10)
=> 7

On Monday, August 16, 2010 10:40:41 pm Iain B. wrote:

It did have a rand function in there, but I removed it because it was
being loaded but the index_in_range wasn’t. I’ve no idea how the rand
function is still getting added if it’s not defined in the file.

irb(main):002:0> Array.public_instance_methods.include? :rand
=> false
irb(main):003:0> Array.private_instance_methods.include? :rand
=> true

Apparently, the core Array class has a private ‘rand’ method?

Iain B. wrote:

So why did it produce two different outputs even though my patch didn’t
add a rand

I’ve no idea, because you haven’t shown the source of your
“local_methods” method, nor the exact sequence of operations to get to
that point.

If you were in a single irb session, and did load ‘extensions/Array.rb’
after changing Array.rb, then any methods added to Array by the old
version will still be present in Array, even if the new Array.rb doesn’t
define them.

and why doesn’t my patch even seem to work anymore?

“Doesn’t work” is not a helpful description of an error.

Post your current code (preferably boiled down to the smallest runnable
example which replicates it). Show exactly what you type, exactly what
you see - results and/or error message - and what you were expecting to
see.

On 17 Aug 2010, at 11:00, Brian C. wrote:

David M. wrote:

Apparently, the core Array class has a private ‘rand’ method?

That’ll be Kernel#rand I expect.

irb(main):001:0> rand(10)

So why did it produce two different outputs even though my patch didn’t
add a rand - and why doesn’t my patch even seem to work anymore?

I’m a tad confused.

Regards,
Iain

On 17 Aug 2010, at 15:36, Brian C. wrote:

Iain B. wrote:

So why did it produce two different outputs even though my patch didn’t
add a rand

I’ve no idea, because you haven’t shown the source of your
“local_methods” method,

class Object
def local_methods
(methods - Object.instance_methods).sort
end
end

nor the exact sequence of operations to get to
that point.

The exact sequence is below, it’s what I posted earlier.

If you were in a single irb session, and did load ‘extensions/Array.rb’
after changing Array.rb, then any methods added to Array by the old
version will still be present in Array, even if the new Array.rb doesn’t
define them.

I quit the irb session, I quit the terminal, I made sure there was no
ruby process running on the system.

and why doesn’t my patch even seem to work anymore?

“Doesn’t work” is not a helpful description of an error.

There is no error, I already gave a full description and everything that
came back except for local_methods.

Post your current code (preferably boiled down to the smallest runnable
example which replicates it). Show exactly what you type, exactly what
you see - results and/or error message - and what you were expecting to
see.

Verbatim (again):

$ irb

r = [1…99, 100…199]
=> [1…99, 100…199]
xs = r.local_methods
=> [:, :, :, :-, :, :=>, :[], :[], :all?, :any?, :assoc, :at, :clear,
:collect, :collect!, :combination, :compact, :compact!, :concat, :count,
:cycle, :delete, :delete_at, :delete_if, :detect, :drop, :drop_while,
:each, :each_cons, :each_index, :each_slice, :each_with_index,
:each_with_object, :empty?, :entries, :fetch, :fill, :find, :find_all,
:find_index, :first, :flatten, :flatten!, :fold, :grep, :group_by,
:include?, :index, :inject, :insert, :join, :last, :length, :map, :map!,
:max, :max_by, :member?, :min, :min_by, :minmax, :minmax_by, :none?,
:one?, :pack, :partition, :permutation, :pop, :product, :push, :rassoc,
:reduce, :reject, :reject!, :replace, :reverse, :reverse!,
:reverse_each, :rindex, :sample, :select, :shift, :shuffle, :shuffle!,
:size, :slice, :slice!, :sort, :sort!, :sort_by, :take, :take_while,
:to_a, :to_ary, :transpose, :uniq, :uniq!, :unshift, :values_at, :zip,
:]
load ‘extensions/Array.rb’
=> true
r.local_methods - xs
=> [:rand]

This is extensions/Array.rb

class Array

def index_in_range( n )
self.each_with_index do |x, i|
return i if x === n
end
return nil
end

end

I’m not expecting to see rand in the list of public methods brought back
by r.local_methods. I’ve even since moved the extensions/Array.rb to a
new location.

Regards,
Iain

Iain B. wrote:

Verbatim (again):

$ irb

r = [1…99, 100…199]
=> [1…99, 100…199]
xs = r.local_methods

If that’s verbatim, then how is your local_methods method getting
loaded? Are you preloading stuff in .irbrc? What other stuff do you have
in there? Try removing it all.

The next thing is, what exact version of ruby are you using? I’m
guessing some variant of 1.9.X, because you are getting symbols. Bugs
in older versions of 1.9 are, ahem, not unknown.

But I can’t replicate your problem with the two versions I have here:

$ cat locmeth.rb
class Object
def local_methods
(methods - Object.instance_methods).sort
end
end
$ cat extarray.rb
class Array
def index_in_range( n )
self.each_with_index do |x, i|
return i if x === n
end
return nil
end
end
$ ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
$ irb --simple-prompt

RUBY_VERSION
=> “1.8.6”
r = [1…99, 100…199]
=> [1…99, 100…199]
xs = r.local_methods
NoMethodError: undefined method `local_methods’ for [1…99,
100…199]:Array
from (irb):3
from :0
require ‘locmeth’
=> true
xs = r.local_methods
=> [“&”, “*”, “+”, “-”, “<<”, “<=>”, “[]”, “[]=”, “all?”, “any?”,
“assoc”, “at”, “clear”, “collect”, “collect!”, “compact”, “compact!”,
“concat”, “delete”, “delete_at”, “delete_if”, “detect”, “each”,
“each_index”, “each_with_index”, “empty?”, “entries”, “fetch”, “fill”,
“find”, “find_all”, “first”, “flatten”, “flatten!”, “grep”, “include?”,
“index”, “indexes”, “indices”, “inject”, “insert”, “join”, “last”,
“length”, “map”, “map!”, “max”, “member?”, “min”, “nitems”, “pack”,
“partition”, “pop”, “push”, “rassoc”, “reject”, “reject!”, “replace”,
“reverse”, “reverse!”, “reverse_each”, “rindex”, “select”, “shift”,
“size”, “slice”, “slice!”, “sort”, “sort!”, “sort_by”, “to_ary”,
“transpose”, “uniq”, “uniq!”, “unshift”, “values_at”, “zip”, “|”]
load ‘extarray.rb’
=> true
r.local_methods - xs
=> [“index_in_range”]

And here’s what I get with the particular variant of 1.9 I have lying
around, a 1.9.2 preview from last year:

$ ruby19 -v
ruby 1.9.2dev (2009-07-18 trunk 24186) [i686-linux]
$ irb19 --simple-prompt

r = [1…99, 100.199]
=> [1…99, 100.199]
require ‘locmeth’
LoadError: no such file to load – locmeth
from (irb):2:in require' from (irb):2 from /usr/local/bin/irb19:12:in
load ‘locmeth.rb’
=> true
xs = r.local_methods
=> [:&, :*, :+, :-, :<<, :<=>, :[], :[]=, :all?, :any?, :assoc, :at,
:clear, :collect, :collect!, :combination, :compact, :compact!, :concat,
:count, :cycle, :delete, :delete_at, :delete_if, :detect, :drop,
:drop_while, :each, :each_cons, :each_index, :each_slice,
:each_with_index, :each_with_object, :empty?, :entries, :fetch, :fill,
:find, :find_all, :find_index, :first, :flatten, :flatten!, :grep,
:group_by, :include?, :index, :inject, :insert, :join, :last, :length,
:map, :map!, :max, :max_by, :member?, :min, :min_by, :minmax,
:minmax_by, :none?, :one?, :pack, :partition, :permutation, :pop,
:product, :push, :rassoc, :reduce, :reject, :reject!, :replace,
:reverse, :reverse!, :reverse_each, :rindex, :sample, :select, :shift,
:shuffle, :shuffle!, :size, :slice, :slice!, :sort, :sort!, :sort_by,
:sort_by!, :take, :take_while, :to_a, :to_ary, :transpose, :uniq,
:uniq!, :unshift, :values_at, :zip, :|]
load ‘extarray.rb’
=> true
r.local_methods - xs
=> [:index_in_range]

These are on a 32-bit Ubuntu Linux Hardy system.

So if the problem is repeatable in your environment, you’ll need to dig
a bit further to see what’s causing it. Possible problems are:
(1) There are multiple versions of extensions/Array.rb reachable from
your $LOAD_PATH, and you’re not loading the one you expect. At some
point in 1.9 development, “.” was removed from $LOAD_PATH.
(2) There’s something odd in .irbrc

Incidentally, there also seems to be some other problem which is
preventing symbols like :& :* and :+ from appearing in your posting, by
the time it reaches ruby-forum.com at least. Possibly something to do
with copy-paste and/or HTML escaping.

Regards,

Brian.

To my surprise I can even load the extensions/Array.rb when it’s not
actually present at that path, which explains a lot. I know the Faker
gem has an extensions/Array.rb with rand in it, because that’s where I
got it from, and it’s installed on my system.

Do all gems become available to irb so they can be loaded using relative
paths even when the library itself has not been required?

$ irb
~

xs = [].local_methods
=> [:, :, :, :-, :, :=>, :[], :[], :all?, :any?, :assoc, :at, :clear,
:collect, :collect!, :combination, :compact, :compact!, :concat, :count,
:cycle, :delete, :delete_at, :delete_if, :detect, :drop, :drop_while,
:each, :each_cons, :each_index, :each_slice, :each_with_index,
:each_with_object, :empty?, :entries, :fetch, :fill, :find, :find_all,
:find_index, :first, :flatten, :flatten!, :fold, :grep, :group_by,
:include?, :index, :inject, :insert, :join, :last, :length, :map, :map!,
:max, :max_by, :member?, :min, :min_by, :minmax, :minmax_by, :none?,
:one?, :pack, :partition, :permutation, :pop, :product, :push, :rassoc,
:reduce, :reject, :reject!, :replace, :reverse, :reverse!,
:reverse_each, :rindex, :sample, :select, :shift, :shuffle, :shuffle!,
:size, :slice, :slice!, :sort, :sort!, :sort_by, :take, :take_while,
:to_a, :to_ary, :transpose, :uniq, :uniq!, :unshift, :values_at, :zip,
:]
load ‘blahblahblah.rb’
LoadError: no such file to load – blahblahblah.rb
from (irb):2:in load' from (irb):2 from /Library/Frameworks/Ruby.framework/Programs/irb:12:in
[].local_methods - xs
=> []
load ‘extensions/Array.rb’
=> true
[].local_methods - xs
=> [:rand]

My .irbrc

require ‘rubygems’
require ‘wirble’
Wirble.init
Wirble.colorize

Easily print methods local to an object’s class

class Object
def local_methods
(methods - Object.instance_methods).sort
end
end

def irb_verbosity_toggle
irb_context.echo ? irb_context.echo = false : irb_context.echo = true
end

#find ri easily
def ri(*names)
system(%{ri #{names.map {|name| name.to_s}.join(" ")}})
end

IRB.conf[:PROMPT][:CUSTOM] = {
:PROMPT_I => "> ",
:PROMPT_S => "%l> ",
:PROMPT_C => " ",
:PROMPT_N => " ",
:RETURN => “=> %s\n”
}
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true

#add fold to the available method names
module Enumerable
alias :fold inject unless Enumerable.method_defined? :fold
end

require ‘pp’

Regards,
Iain

On 17 Aug 2010, at 16:36, Brian C. wrote:

find it, unless it finds another one earlier in the path.
Posted via http://www.ruby-forum.com/.

I see, that makes sense. I assumed that since I was giving a path to
load that it wouldn’t search through the $: paths.

Thanks for your help.

Regards,
Iain

Iain B. wrote:

find it, unless it finds another one earlier in the path.

I see, that makes sense. I assumed that since I was giving a path to
load that it wouldn’t search through the $: paths.

The actual behaviour of Kernel#load is not obvious

Experimentation with 1.9.2-preview2 suggests:

  • load ‘foo.rb’ will find foo.rb relative to $:

  • if that fails, load ‘foo.rb’ will also find foo.rb in the current
    directory, even if “.” is not in $: (but require won’t)

As far as I can see, this difference is not documented in ri Kernel#load

Iain B. wrote:

Do all gems become available to irb so they can be loaded using relative
paths even when the library itself has not been required?

In ruby 1.9, rubygems is activated automatically - you don’t need
require ‘rubygems’

There isn’t really any such thing as “requiring the library itself”. A
library is just a collection of .rb files. So if
…/gems/foo-1.2.3/lib/bar/baz.rb exists, then require “bar/baz” will
find it, unless it finds another one earlier in the path.

So I think the mystery is solved :slight_smile:

For development purposes, you could do

irb -I.

to put the current directory at the front of the search path - or the
equivalent in .irbrc