# What about allowing to specify, which end belongs to which start?

**URL:** <https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133>\
**Category:** ruby-talk\
**Created:** [9 July 2010 19:05 UTC](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133 "2010-07-09T19:05:15Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![Jan\_Lelis](https://avatars.discourse-cdn.com/v4/letter/j/73ab20/32.png) [@Jan\_Lelis](https://rubytalk.org/u/Jan_Lelis)\
**Post date:** [12 July 2010 19:30 UTC](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133/21 "2010-07-12T19:30:48Z")

</div>

> \> def test  
> \> while 1  
> \> puts (1..9).each\_slice(3).map do |slice|  
> \> sum = slice.inject do |acc, ele|  
> \> acc + ele  
> \> end  
> \>  
> \> if sum \> 6  
> \> 42  
> \> else  
> \> 99  
> \> end~if  
> \> end~do.join ','  
> \> end~while  
> \> end  
> \>  
> Hi,  
> I know it's a bit of a contrived example, and I'm not advocating a version  
> of "Ruby Golf" here, but if I saw this method in some code I was maintaining  
> I would refactor it to something like:
> 
> def test  
> &nbsp;&nbsp;while 1  
> &nbsp;&nbsp;&nbsp;&nbsp;puts (1..9).each\_slice(3).map do |slice|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum = slice.inject { |acc, ele| acc + ele }  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum \> 6 ? 42 : 99  
> &nbsp;&nbsp;&nbsp;&nbsp;end.join(',')  
> &nbsp;&nbsp;end  
> end
> 
> ...or even better, move the "summing" to another method...
> 
> def test  
> &nbsp;&nbsp;while 1  
> &nbsp;&nbsp;&nbsp;&nbsp;puts (1..9).each\_slice(3).map do |slice|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;calculate\_sum \> 6 ? 42 : 99  
> &nbsp;&nbsp;&nbsp;&nbsp;end.join(',')  
> &nbsp;&nbsp;end  
> end
> 
> def calculate\_sum(items)  
> &nbsp;&nbsp;items.inject { |acc, ele| acc + ele }  
> end
> 
> I think most cases where the end~if syntax is "necessary" would be better off  
> (e.g. more readable) with a healthy dose of refactoring.

Of course, the example was made up to demonstrate the ends and not real  
world code. I would not write it in this way, either...

This one is from existing code:

&nbsp;&nbsp;module ABC

&nbsp;&nbsp;&nbsp;&nbsp;# ...

&nbsp;&nbsp;&nbsp;&nbsp;def abc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.each do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if x

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case lorem

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

---

<div class="post-metadata">

**Author:** ![Bob\_Nadler](https://avatars.discourse-cdn.com/v4/letter/b/d78d45/32.png) [@Bob\_Nadler](https://rubytalk.org/u/Bob_Nadler)\
**Post date:** [12 July 2010 20:17 UTC](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133/22 "2010-07-12T20:17:25Z")

</div>

My general rule of thumb is to put long case statements (if I can't avoid  
using them) into their own separate method. So I would refactor the code to:

module ABC

&nbsp;&nbsp;def abc  
&nbsp;&nbsp;&nbsp;&nbsp;x.each do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;some\_method\_name\_that\_describes\_what\_case\_statement\_does(lorem) if x  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;def some\_method\_name\_that\_describes\_what\_case\_statement\_does(value)  
&nbsp;&nbsp;&nbsp;&nbsp;case lorem

&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

end

As an aside, take a look at Refactoring: Ruby Edition[1]. It covers ways of  
dealing with long methods, case statements, and other situations that  
cause difficulties trying  
to match up "end"'s.

[1] [Amazon.com](http://www.amazon.com/Refactoring-Ruby-Jay-Fields/dp/0321603508)

> **···**
>
> On Mon, Jul 12, 2010 at 3:30 PM, Jan Lelis \<prog@janlelis.de\> wrote:
> 
> > > \> def test  
> > > \> while 1  
> > > \> puts (1..9).each\_slice(3).map do |slice|  
> > > \> sum = slice.inject do |acc, ele|  
> > > \> acc + ele  
> > > \> end  
> > > \>  
> > > \> if sum \> 6  
> > > \> 42  
> > > \> else  
> > > \> 99  
> > > \> end~if  
> > > \> end~do.join ','  
> > > \> end~while  
> > > \> end  
> > > \>  
> > > Hi,  
> > > I know it's a bit of a contrived example, and I'm not advocating a version  
> > > of "Ruby Golf" here, but if I saw this method in some code I was maintaining  
> > > I would refactor it to something like:
> > > 
> > > def test  
> > > while 1  
> > > puts (1..9).each\_slice(3).map do |slice|  
> > > sum = slice.inject { |acc, ele| acc + ele }  
> > > sum \> 6 ? 42 : 99  
> > > end.join(',')  
> > > end  
> > > end
> > > 
> > > ...or even better, move the "summing" to another method...
> > > 
> > > def test  
> > > while 1  
> > > puts (1..9).each\_slice(3).map do |slice|  
> > > calculate\_sum \> 6 ? 42 : 99  
> > > end.join(',')  
> > > end  
> > > end
> > > 
> > > def calculate\_sum(items)  
> > > items.inject { |acc, ele| acc + ele }  
> > > end
> > > 
> > > I think most cases where the end~if syntax is "necessary" would be better off  
> > > (e.g. more readable) with a healthy dose of refactoring.
> > 
> > Of course, the example was made up to demonstrate the ends and not real  
> > world code. I would not write it in this way, either...
> > 
> > This one is from existing code:
> > 
> > module ABC
> > 
> > # ...
> > 
> > def abc  
> > x.each do  
> > if x
> > 
> > ```
> > case lorem
> > 
> > when :ipsum
> > \# \.\.\.
> > when :ipsum
> > \# \.\.\.
> > when :ipsum
> > \# \.\.\.
> > when :ipsum
> > \# \.\.\.
> > else
> > \# \.\.\.
> > end
> > end
> > end
> > 
> > ```
> > 
> > end  
> > end

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [13 July 2010 08:41 UTC](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133/23 "2010-07-13T08:41:20Z")

</div>

> > \> def test  
> > \> while 1  
> > \> puts (1..9).each\_slice(3).map do |slice|  
> > \> sum = slice.inject do |acc, ele|  
> > \> acc + ele  
> > \> end  
> > \>  
> > \> if sum \> 6  
> > \> 42  
> > \> else  
> > \> 99  
> > \> end~if  
> > \> end~do.join ','  
> > \> end~while  
> > \> end  
> > \>  
> > Hi,  
> > I know it's a bit of a contrived example, and I'm not advocating a version  
> > of "Ruby Golf" here, but if I saw this method in some code I was maintaining  
> > I would refactor it to something like:
> > 
> > def test  
> > while 1  
> > puts (1..9).each\_slice(3).map do |slice|  
> > sum = slice.inject { |acc, ele| acc + ele }  
> > sum \> 6 ? 42 : 99  
> > end.join(',')  
> > end  
> > end
> > 
> > ...or even better, move the "summing" to another method...
> > 
> > def test  
> > while 1  
> > puts (1..9).each\_slice(3).map do |slice|  
> > calculate\_sum \> 6 ? 42 : 99  
> > end.join(',')  
> > end  
> > end
> > 
> > def calculate\_sum(items)  
> > items.inject { |acc, ele| acc + ele }  
> > end
> > 
> > I think most cases where the end~if syntax is "necessary" would be better off  
> > (e.g. more readable) with a healthy dose of refactoring.
> 
> Of course, the example was made up to demonstrate the ends and not real  
> world code. I would not write it in this way, either...
> 
> This one is from existing code:
> 
> module ABC
> 
> # ...
> 
> def abc  
> x.each do  
> if x

This is probably a different criterion, otherwise the "if" statement  
would be superfluous.

> ```
> case lorem
> 
> when :ipsum
> \# \.\.\.
> when :ipsum
> \# \.\.\.
> when :ipsum
> \# \.\.\.
> when :ipsum
> \# \.\.\.
> else
> \# \.\.\.
> end
> end
> end
> 
> ```
> 
> end  
> end

If you have lengthy case statements you should consider a different  
approach because they are relatively slow and awkward to read (as you  
noticed already). State and strategy pattern come to mind. Often it  
is also advisable to do something like this:

class Foo  
&nbsp;&nbsp;MY\_OPERATION = {  
&nbsp;&nbsp;&nbsp;&nbsp;String =\> lambda {|x| Integer(x)},  
&nbsp;&nbsp;&nbsp;&nbsp;Fixnum =\> lambda {|x| x},  
&nbsp;&nbsp;&nbsp;&nbsp;IO =\> lambda {|x| Integer(x.gets.chomp)}  
&nbsp;&nbsp;}

&nbsp;&nbsp;def work(obj)  
&nbsp;&nbsp;&nbsp;&nbsp;MY\_OPERATION.fetch(obj.class) do |cl|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ArgumentError, "Dunno what to do with #{obj.inspect}"  
&nbsp;&nbsp;&nbsp;&nbsp;end[obj]  
&nbsp;&nbsp;end  
end

irb(main):014:0\> f = Foo.new  
=\> #\<Foo:0x10297f34\>  
irb(main):015:0\> f.work 123  
=\> 123  
irb(main):016:0\> f.work "456"  
=\> 456  
irb(main):017:0\> f.work $stdin  
789  
=\> 789  
irb(main):018:0\> f.work [1,2,3]  
ArgumentError: Dunno what to do with [1, 2, 3]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):10:in `block in work'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):9:in `fetch'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):9:in `work'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):18  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from /opt/bin/irb19:12:in `\<main\>'  
irb(main):019:0\>

You can view this as a way to add methods to types without modifying them.

Kind regards

robert

> **···**
>
> 2010/7/12 Jan Lelis \<prog@janlelis.de\>:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![Mark\_T](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mark\_T](https://rubytalk.org/u/Mark_T)\
**Post date:** [13 July 2010 01:33 UTC](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133/24 "2010-07-13T01:33:16Z")

</div>

In favour of:  
\*) Keeping with designer's intentions. Least surprise being one of.  
\*) Keeping understandability as a premium.  
\*) Using inline documentation where self.doco is not enough.  
\*) Readability is key, using less verbosity being part of this.  
\*) Refactoring can be from different perspectives, one's own code, an  
imported library or maintenance.  
Refactoring a previous post I would use hanging indents to 'indicate'  
methods, compress trailing ends on lastline.  
Also, I use one space for each indent, this gives me an indicator at  
the end of a .code-block. as to having correct closing(s).  
I like to read the code, not the end markers.  
Different approaches for different code.

module ABC  
def abc  
&nbsp;&nbsp;&nbsp;x.each do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;some\_method\_name\_that\_describes\_what\_case\_statement\_does(lorem)  
if x end end

def some\_method\_name\_that\_describes\_what\_case\_statement\_does(value)  
&nbsp;&nbsp;&nbsp;case lorem  
&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;when :ipsum  
&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;# ... end end end

> **···**
>
> ---------------------------------------  
> MarkT

[Previous page](https://rubytalk.org/t/what-about-allowing-to-specify-which-end-belongs-to-which-start/59133.md?page=1)
