Forum: Ruby on Rails Combine if and do in a single line?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mario G. (Guest)
on 2009-05-28 05:17
Is there a  way to combine if and do into a single line?

items.each do |item| if current_user.admin?
  #do stuff
end

Thanks!
Freddy A. (Guest)
on 2009-05-28 05:50
(Received via mailing list)
items.each { |item| item.stuff? } if current_user.admin?
Jonathan R. (Guest)
on 2009-05-30 21:31
Mario Gr wrote:
> Is there a  way to combine if and do into a single line?
>
> items.each do |item| if current_user.admin?
>   #do stuff
> end
>
> Thanks!



Freddy A. wrote:
> items.each { |item| item.stuff? } if current_user.admin?

Which you actually COULD write like this too, but I'm not sure if it
would be considered easily readable:

items.each do |item|
   #do stuff
end if current_user.admin?

The {| | } and the 'do' syntaxes are interchangeable in all ways.  More
of a Ruby question than a Rails one.
Marnen L. (Guest)
on 2009-05-30 22:03
Jonathan R. wrote:
[...]
> The {| | } and the 'do' syntaxes are interchangeable in all ways.

Almost.  I've run across a couple of cases where one works and the other
doesn't -- one creates a Proc and the other doesn't, or something like
that.  But that's vanishingly rare, and 99 times out of 100, you will
not go wrong to treat them as interchangeable.

> More
> of a Ruby question than a Rails one.

Yup.

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
removed_email_address@domain.invalid
Frederick C. (Guest)
on 2009-05-30 22:16
(Received via mailing list)
On May 30, 7:03 pm, Marnen Laibow-Koser <rails-mailing-l...@andreas-
s.net> wrote:
> Jonathan R. wrote:
>
> [...]
>
> > The {| | } and the 'do' syntaxes are interchangeable in all ways.  
>
> Almost.  I've run across a couple of cases where one works and the other
> doesn't -- one creates a Proc and the other doesn't, or something like
> that.  

{} binds more tightly than do..end - in some cases this can lead to
your block being passed to the 'wrong' method:

def foo(x)
  puts "foo #{block_given?}"
end

def bar
  puts "bar #{block_given?}"
end

running foo bar {} outputs

bar true
foo false

but running

foo bar do
end

outputs

boo false
foo true

Fred
Jonathan R. (Guest)
on 2009-05-30 22:26
Frederick C. wrote:
> {} binds more tightly than do..end - in some cases this can lead to
> your block being passed to the 'wrong' method:

Interesting, makes sense.

Personally, that's one reason I don't like making method calls without
parens, or doing anything else that relies on non-obvious
order-of-evaluation-binding just to save a couple of parens.

foo(  bar {} )
or
foo( bar do
end )

will both do the same thing. Although the latter is kind of weird style,
if I need a multi-line block for bar, I'd personally just use a
temporary var instead.

result = bar do
end
foo(result)

But everyone's got their own style, I guess. Of course you COULD use
{||} with multi-lines too, but it would also be stylistically weird in
my opinion in that case.

foo bar {|a|
   stuff
   more stuff
   }

That's just weird. And if I DID it, I'd still want to put parens in
around foo's argument, which would make it even weirder looking.

Jonathan
This topic is locked and can not be replied to.