0

The following code works perfectly.

@doc = open(link) { |f| Hpricot(f) }

But I want to use the following code, which doesn't seem to play well with the Hpricot block (e.g. @doc is a TempFile object, not a Hpricot document object)

@doc = resolve_link(link) { |f| Hpricot(f) }

def resolve_link(link)
  begin
    return open(link)
  rescue
    logger.debug("#{$!} for link #{link}")
    raise Exceptions::ErrorResolvingLink.new("Cannot resolve link #{link}.")
  end
end

Any idea how I can get the second version of the code to work?

deruse
  • 2,851
  • 7
  • 40
  • 60
  • Irrelevant to the question, but you can omit `begin` and `end` leaving `rescue` in immediate environment of `def`. – sawa Jun 12 '11 at 07:45
  • @sawa: OTOH, the `begin` is a nice visual marker that you're about to do some exception handling and the reader should pay attention. – mu is too short Jun 12 '11 at 07:48
  • @mu is too short I usually bring `rescue` at the same indent level as `def` and its corresponding `end`, so `rescue` outstands enough. Whenever you meet `rescue`, you can tell that whatever beyond is error handeling. – sawa Jun 12 '11 at 07:54
  • @sawa: It is really a question of style (and hence personal preference), I just find that it is clearer to be warned that something is about to happen before it happens rather than being told afterwards. – mu is too short Jun 12 '11 at 18:44

2 Answers2

5

You're calling resolve_link with a block but you're not passing that block down to open. Try this instead:

def resolve_link(link, &block)
  begin
    return open(link, &block)
  #...
mu is too short
  • 426,620
  • 70
  • 833
  • 800
1

You have to use yield to invoke the block.

See this answer for a very simple example:

Blocks and yields in Ruby

So something along the lines

def resolve_link(link)
    ...
    yield ( some_value_to_pass_to_the_block )
    ...
end

Should work.

Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569