Skip to content

Instantly share code, notes, and snippets.

@tjmcewan
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjmcewan/a7e4feb2976a93a5eef9 to your computer and use it in GitHub Desktop.
Save tjmcewan/a7e4feb2976a93a5eef9 to your computer and use it in GitHub Desktop.
I dunno...
# 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)>
@willrax
Copy link

willrax commented Jun 27, 2014

ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]

 pry                                                                                                                                                                                                                                                                                                   2.1.1 staging ac4dfa3
[1] pry(main)> def plusone(x)
[1] pry(main)*   x + 1
[1] pry(main)* end
=> :plusone
[2] pry(main)> [1,2,3].map(&:plusone)
ArgumentError: wrong number of arguments (0 for 1)
from (pry):1:in `plusone'
[3] pry(main)> [1,2,3].map { |a| plusone(a) }
=> [
    [0] 2,
    [1] 3,
    [2] 4
]

@willrax
Copy link

willrax commented Jun 27, 2014

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]

@damncabbage
Copy link

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

@willrax
Copy link

willrax commented Jun 27, 2014

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"]

@tjmcewan
Copy link
Author

Bad Will! No.

@tjmcewan
Copy link
Author

@willrax
Copy link

willrax commented Jun 27, 2014

Must just be an irb / pry thing if that's the case.

@damncabbage
Copy link

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>'

WHAT.

@damncabbage
Copy link

@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.

@tjmcewan
Copy link
Author

@damncabbage I think that's exactly my problem - I was trying to write simple functions I could just map...

@damncabbage
Copy link

@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.)

@tjmcewan
Copy link
Author

@damncabbage or use a lambda plusone = ->(x) { x + 1 } and [1,2,3].map(&plusone)

@warrenseen
Copy link

@damncabbage is almost right.

irb(main):005:0> [1,2,3].map(&method(:plusone))
=> [2, 3, 4]

@damncabbage
Copy link

Better:

> [1,2,3].map(&"1".method(:foo))
=> [2, 3, 4]

... quiet sobbing

@damncabbage
Copy link

> 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.

@ddd1600
Copy link

ddd1600 commented Jun 27, 2014

class Numeric
  def plusone
    self + 1
  end
end

[1,2,3].map(&:plusone)
#=> [2,3,4]

Sorry guys this is all my fault

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment