用于运行代码两次的Ruby习惯用法("中间代码")

Jo *_*iss 2 ruby

在我的Capybara + Webdriver AJAX测试中,我看到了这样的代码模式:

page.should have_selector('foo.bar > baz')  # added dynamically by JS
visit current_page
page.should have_selector('foo.bar > baz')  # still there after reload
Run Code Online (Sandbox Code Playgroud)

我把它提取到一个persist辅助函数中,这样做

def persist
  yield
  visit current_page
  yield
end
Run Code Online (Sandbox Code Playgroud)

问题:在没有帮助函数的情况下,是否有一个紧凑的成语来内联相同的内容?

我能想到的最短的是

2.times { |i|
    page.should have_selector('foo.bar > baz')
    visit current_page if i == 0
}
Run Code Online (Sandbox Code Playgroud)

这是干的,但仍然很难看.

编辑:我认为马克的评论是正确的,我正在坚持persist这个特定用例的帮助.也就是说,下面的答案中有几个好的(和有趣的)想法.

编辑2:如果有人想复制我的persist例子:使用RSpec,它把一个很有用@__memoized = {}visit current_page,以刷新任何让利的页面重新加载后会过时的控股节点(否则你得到的ObsoleteElementError).

edg*_*ner 5

在我看来,重复一行是没有错的,如果它使代码更具可读性.您的案例似乎是这种合理重复的一个很好的例子:)

如果你发现自己重复了很多模式,你可能希望延伸Object类似的东西

def should_still(predicate)
  should predicate
  yield
  should predicate
end
Run Code Online (Sandbox Code Playgroud)

那么你可以编写像这样的紧凑语句

page.should_still have_selector('foo.bar > baz') { visit current_page }
Run Code Online (Sandbox Code Playgroud)