-
-
Save tjmcewan/a7e4feb2976a93a5eef9 to your computer and use it in GitHub Desktop.
# http://stackoverflow.com/a/19323467/320438 | |
def plusone(x) | |
x + 1 | |
end | |
[1,2,3].map(&:plusone) |
~$ ruby -v *[master] | |
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0] | |
~$ irb *[master] | |
irb(main):001:0> def plusone(x) | |
irb(main):002:1> x + 1 | |
irb(main):003:1> end | |
=> :plusone | |
irb(main):004:0> | |
irb(main):005:0* [1,2,3].map(&:plusone) | |
NoMethodError: private method `plusone' called for 1:Fixnum | |
from (irb):5:in `map' | |
from (irb):5 | |
from /Users/tim/.rubies/ruby-2.1.2/bin/irb:11:in `<main>' | |
irb(main):006:0> |
~$ ruby -v *[master] | |
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0] | |
~$ pry *[master] | |
[1] pry(main)> def plusone(x) | |
[1] pry(main)* x + 1 | |
[1] pry(main)* end | |
=> :plusone | |
[2] pry(main)> | |
[3] pry(main)> [1,2,3].map(&:plusone) | |
ArgumentError: wrong number of arguments (0 for 1) | |
from (pry):1:in `plusone' | |
[4] pry(main)> |
irb(main):008:0> class Integer
irb(main):009:1> def plusone
irb(main):010:2> self + 1
irb(main):011:2> end
irb(main):012:1> end
=> :plusone
irb(main):013:0> [1,2,3].map(&:plusone)
=> [2, 3, 4]
O_O
[1,2,3].map(&:plusone)
is equivalent to [1,2,3].map { |a| a.plusone }
, not [1,2,3].map { |a| plusone(a) }
.
(I'm more confused as to why Fixnum has the method at all, even private. Does something else in the code you're loading monkey-patch that method into the class or something?)
irb(main):001:0> def plusone
irb(main):002:1> "hello"
irb(main):003:1> end
=> :plusone
irb(main):004:0> [1,2,3].map(&:plusone)
NoMethodError: private method `plusone' called for 1:Fixnum
from (irb):4:in `map'
from (irb):4
from /Users/Will/.rbenv/versions/2.1.1/bin/irb:11:in `<main>'
irb(main):006:0> [1,2,3].map {|i| i.send(:plusone) }
=> ["hello", "hello", "hello"]
Bad Will! No.
Must just be an irb / pry thing if that's the case.
irb(main):014:0> def foo(x); x + 1; end
=> nil
irb(main):015:0> "1".foo
NoMethodError: private method `foo' called for "1":String
from (irb):15
from /Users/rhoward/.rbenv/versions/2.0.0-p451/bin/irb:12:in `<main>'
irb(main):016:0> 1.foo
NoMethodError: private method `foo' called for 1:Fixnum
from (irb):16
from /Users/rhoward/.rbenv/versions/2.0.0-p451/bin/irb:12:in `<main>'
@willrax: Nope. Not just IRB.
$ cat > nope.rb <<-EOF
def foo(x); x + 1; end
puts "1".foo
EOF
$ ruby nope.rb
nope.rb:2:in `<main>': private method `foo' called for "1":String (NoMethodError)
... Well.
@damncabbage I think that's exactly my problem - I was trying to write simple functions I could just map...
@tjmcewan: You can't use the :method.to_proc
/ &:method
shortcut; you need to spell it out in the block a la [1,2,3].map {|a| foo(a) }
.
(And then cry yourself to sleep.)
@damncabbage or use a lambda plusone = ->(x) { x + 1 }
and [1,2,3].map(&plusone)
@damncabbage is almost right.
irb(main):005:0> [1,2,3].map(&method(:plusone))
=> [2, 3, 4]
Better:
> [1,2,3].map(&"1".method(:foo))
=> [2, 3, 4]
... quiet sobbing
> def foo(x); x + 1; end
=> nil
> method(:foo).owner
=> Object
> 1.method(:foo).owner
=> Object
> 1.class.ancestors
=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
# WELL HELLO, OBJECT.
Well, that solves that mystery.
class Numeric
def plusone
self + 1
end
end
[1,2,3].map(&:plusone)
#=> [2,3,4]
Sorry guys this is all my fault
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]