Have I been staring at the screen too long?

I

Iain Barnett

$ irb
r =3D [1..99, 100..199] =3D> [1..99, 100..199]
xs =3D r.local_methods=20
=3D> [:, :, :, :-, :, :=3D>, :[], :[], :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?, :eek:ne?, :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' =3D> true
r.local_methods - xs
=3D> [:rand]

This is extensions/Array.rb

class Array
=20
def index_in_range( n )
self.each_with_index do |x, i|
return i if x =3D=3D=3D n
end
return nil
end

=20
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
 
D

David Masover

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?
 
I

Iain Barnett

=20
That'll be Kernel#rand I expect.
=20
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
 
B

Brian Candler

Iain said:
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.
 
I

Iain Barnett

=20
I've no idea, because you haven't shown the source of your=20
"local_methods" method,

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

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

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'=20
after changing Array.rb, then any methods added to Array by the old=20
version will still be present in Array, even if the new Array.rb = doesn't=20
define them.

I quit the irb session, I quit the terminal, I made sure there was no =
ruby process running on the system.
=20
=20
"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.
=20
Post your current code (preferably boiled down to the smallest = runnable=20
example which replicates it). Show exactly what you type, exactly what=20=
you see - results and/or error message - and what you were expecting = to=20
see.

Verbatim (again):

$ irb
r =3D [1..99, 100..199] =3D> [1..99, 100..199]
xs =3D r.local_methods=20
=3D> [:, :, :, :-, :, :=3D>, :[], :[], :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?, :eek:ne?, :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' =3D> true
r.local_methods - xs
=3D> [:rand]

This is extensions/Array.rb

class Array

def index_in_range( n )
self.each_with_index do |x, i|
return i if x =3D=3D=3D 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
 
I

Iain Barnett

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 =3D [].local_methods=20
=3D> [:, :, :, :-, :, :=3D>, :[], :[], :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?, :eek:ne?, :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 =
` said:
[].local_methods - xs =3D> []
load 'extensions/Array.rb' =3D> true
[].local_methods - xs =3D> [:rand]
=20


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 =3D false : irb_context.echo =3D =
true
end

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

IRB.conf[:pROMPT][:CUSTOM] =3D {
:pROMPT_I =3D> "> ",
:pROMPT_S =3D> "%l> ",
:pROMPT_C =3D> " ",
:pROMPT_N =3D> " ",
:RETURN =3D> "=3D> %s\n"
}
IRB.conf[:pROMPT_MODE] =3D :CUSTOM
IRB.conf[:AUTO_INDENT] =3D true


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

require 'pp'


Regards,
Iain=
 
B

Brian Candler

Iain said:
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=> ["&", "*", "+", "-", "<<", "<=>", "[]", "[]=", "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", "|"]=> ["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
=> [:&, :*, :+, :-, :<<, :<=>, :[], :[]=, :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?, :eek:ne?, :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, :|]=> [: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.
 
B

Brian Candler

Iain said:
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 :)

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
 
I

Iain Barnett

=20
In ruby 1.9, rubygems is activated automatically - you don't need=20
require 'rubygems'
=20
There isn't really any such thing as "requiring the library itself". A=20=
library is just a collection of .rb files. So if=20
.../gems/foo-1.2.3/lib/bar/baz.rb exists, then require "bar/baz" will=20=
find it, unless it finds another one earlier in the path.
=20
So I think the mystery is solved :)
=20
For development purposes, you could do
=20
irb -I.
=20
to put the current directory at the front of the search path - or the=20=
equivalent in .irbrc
--=20
Posted via http://www.ruby-forum.com/.
=20


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=
 
B

Brian Candler

Iain said:
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
 

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

Similar Threads

Subclassing Array 7

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top