Skip to content

Instantly share code, notes, and snippets.

Created July 19, 2015 13:02
Show Gist options
  • Save anonymous/2b6369fea84ae625c9bb to your computer and use it in GitHub Desktop.
Save anonymous/2b6369fea84ae625c9bb to your computer and use it in GitHub Desktop.
# here is an expectation that utilizes a custom RSpec matcher, yield_variables:
specify { expect{ |p| [3,4,5].my_each(&p) }.to yield_variables [3,4,5] }
# my yield_variables matcher's matches? method utilizes a custom class called Probe:
...
def matches? block
ap Probe.probe block
# note i am inspecting what is returned by Probe.probe with ap
end
...
class Probe
attr_accessor :yielded_args
def initialize
self.yielded_args = []
end
def self.probe(block)
probe = new
block.call(probe)
probe.yielded_args
end
def to_proc
Proc.new { |*args| yielded_args << args }
end
end
# now my ap inside matches? reports this: [3,4,5] That is what I expect. However, I have no idea how the Probe class works!!
# Problem 1) the matches? block
# Normally, the argument we pass to matches? is what we expect the subject to return. i.e, I expect [3,4,5] to be
# passed into block.
# Instead, |p| [3,4,5].my_each(&p) is passed into block, as a proc. Why is this?
# Problem 2) block.call(probe)
# I'm a bit shakey on procs so please explain slowly. But basically, here we take a new instance of my Probe class and 'send' the # block to it, as an argument. That's how I'd explain it to the best of my abilities, but I might have it totally wrong so please # explain slowly.
# Problem 3) How is to_proc called?
# How on earth is .to_proc called automatically? I believe it's called automatically by block.call(probe). Is to_proc an
# automatically called method like initialize? Is it automatically called whenever the class is sent to a proc? (Btw, the
# phrase the class is sent to a proc doesn't even make 100% sense to me - please explain. Like, the block isn't passed into
# the class as an # # argument anymore. Or if the block is passed as an argument the block.call syntax feels really weird and
# backwards)
# Problem 4) to_proc
# How does to_proc have access to the expectation's subject i.e. |p| [3,4,5].my_each(&p) ? How is Proc.new 's *args automatically # populated with every single possible yield argument, even though I've only passed in |p| ? How does **Proc.new loop along with
# my my_each, incrementally placing all my args in an array?** How does Proc.new have any knowledge
# of the subject |p| [3,4,5].my_each(&p) ? How?? Explain please, and thanks, I know this is a bit of an ask.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment