# Pythonic indentation (or: beating a dead horse)

**URL:** <https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479>\
**Category:** ruby-talk\
**Created:** [19 May 2009 21:40 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479 "2009-05-19T21:40:02Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![Greg\_Brown1](https://avatars.discourse-cdn.com/v4/letter/g/258eb7/32.png) [@Greg\_Brown1](https://rubytalk.org/u/Greg_Brown1)\
**Post date:** [20 May 2009 20:39 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/81 "2009-05-20T20:39:34Z")

</div>

I didn't accidentally illustrate anything. And everything has a  
cost. Why don't you list for yourself the cost of editing code with  
significant white space?  
Maybe for you, those costs are irrelevant. For me, the costs of ends  
in Ruby code are irrelevant.

But your point was about \*readability\* not maintainability. I don't  
think that good project organization is a 'cost' to readability.

> **···**
>
> On Wed, May 20, 2009 at 4:32 PM, Juan Zanos \<juan\_zanos@talkhouse.com\> wrote:
> 
> > You want me to have even more files and spend even more time folding and  
> > unfolding things. And you assume I use a crummy editor and there is a  
> > better one that magically makes a surprising number of wasted lines  
> > irrelevant. I think you accidentally illustrated that extra lines have a  
> > cost.

---

<div class="post-metadata">

**Author:** ![Greg\_Brown1](https://avatars.discourse-cdn.com/v4/letter/g/258eb7/32.png) [@Greg\_Brown1](https://rubytalk.org/u/Greg_Brown1)\
**Post date:** [20 May 2009 20:55 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/82 "2009-05-20T20:55:11Z")

</div>

I still think this is a straw man. I'm rarely concerned with the  
'readability' of a whole page of code.  
I feel like there is something wrong with my design when I have to  
think at that level.

For what it's worth, I actually can care less whether whitespace is  
significant or not. Significant whitespace doesn't bother me in Haml.  
The lack of significant whitespace doesn't bother me in Ruby.

What does bother me is that people somehow think this issue is so  
important and dire, yet they think it's someone else's job to fix it.  
If you want Ruby with significant whitespace, build it. Don't try to  
convince folks who don't care about the issue.

-greg

> **···**
>
> On Wed, May 20, 2009 at 4:40 PM, Ryo Furue \<furue@hawaii.edu\> wrote:
> 
> > On May 20, 9:50 am, Gregory Brown \<gregory.t.br...@gmail.com\> wrote:
> 
> > > Rick's point remains. If this is an issue you're facing, get a better editor.
> > 
> > But, the amount of meaningful code displayed in a single screenshot  
> > still suffers. A screenful is a chunk of code  
> > you can see without scrolling or jumping. The more meaning it  
> > contains, the better you understand the code (as long as the meaning  
> > is cleanly laid out, of course).

---

<div class="post-metadata">

**Author:** ![Juan\_Zanos](https://avatars.discourse-cdn.com/v4/letter/j/4da419/32.png) [@Juan\_Zanos](https://rubytalk.org/u/Juan_Zanos)\
**Post date:** [21 May 2009 17:41 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/83 "2009-05-21T17:41:39Z")

</div>

The Ant XML example is a bit ironic. Ant's creator regrets using XML. He believes that he should have used a scripting language instead. Take a look at Rake and you'll see a DSL that does what Ant does and more.

> **···**
>
> On May 21, 2009, at 1:26 PM, Steven Arnold wrote:
> 
> > On May 21, 2009, at 8:06 AM, Roger Pack wrote:
> > 
> > > Interesting--it's been awhile since I used C...what would  
> > > macros...essentially do? An example of them?
> > 
> > I was thinking more like Lisp macros. Check out:
> > 
> > &nbsp;&nbsp;&nbsp;[defmacro - The Nature of Lisp](http://www.defmacro.org/ramblings/lisp.html)
> > 
> > steven

---

<div class="post-metadata">

**Author:** ![Steven\_Arnold](https://avatars.discourse-cdn.com/v4/letter/s/3bc359/32.png) [@Steven\_Arnold](https://rubytalk.org/u/Steven_Arnold)\
**Post date:** [22 May 2009 03:56 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/84 "2009-05-22T03:56:47Z")

</div>

Me too. It's interesting how seemingly small changes can generate a lot of unexpected corner cases and unforeseen consequences. Of course, one could argue that using indentation does not preclude using explicit blocks in the same file. I doubt, for example, that anyone wishing to remove the 'end' keyword would wish to disallow something like:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array\_of\_strings\_that\_are\_numbers.sort! {|a,b| a.to\_i \<=\> b.to\_i}

...even though the {} brackets are the same as do..end.

If explicit blocks were allowed in the same file where blocks were, by default, determined by indentation, then you could have your cake and eat it too in the example above.

Nevertheless, I think your gut feel is correct......this would be a tricky thing to do right.

steven

> **···**
>
> On May 21, 2009, at 10:24 PM, Tony Arcieri wrote:
> 
> > Quite frequently I do something like:
> > 
> > str = [a, b, c].map do |x|  
> > thing1 = do\_something\_to x  
> > thing2 = do\_something\_else\_to x  
> > "#{thing1}:#{thing2}"  
> > end.join(",")

---

<div class="post-metadata">

**Author:** ![James\_Britt3](https://avatars.discourse-cdn.com/v4/letter/j/b782af/32.png) [@James\_Britt3](https://rubytalk.org/u/James_Britt3)\
**Post date:** [24 May 2009 20:42 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/85 "2009-05-24T20:42:19Z")

</div>

Reid Thompson wrote:

> James Britt wrote:
> 
> > I've wondered if this sort thing is a problem in Python; perhaps it is less likely there that any accidental indent or out-dent will still give you well-formed code.
> 
> I've only minimally looked at python, but I'm pretty sure that it will throw an error when indentation is fouled.

Sure, if in fact the indentation is fouled.

My concern is that you can mistakenly add 4 spaces instead of two, or vice versa, and get valid code (i.e. the parser does not see anything technically wrong) yet not have the code you really wanted.

James

---

<div class="post-metadata">

**Author:** ![John\_W\_Higgins1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/john_w_higgins1/32/1922_2.png) [@John\_W\_Higgins1](https://rubytalk.org/u/John_W_Higgins1)\
**Post date:** [25 May 2009 19:01 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/86 "2009-05-25T19:01:38Z")

</div>

Finally, I thought, an example! Time to dig out that old Ruby script

> for preprocessing Python-style Ruby files... ah, there it is, on the  
> old MacBook Pro... copy it over to the current computer... hmm, no  
> doc... throw in a few quick and dirty patches to make it run; after  
> all, this is just a proof-of-concept, right? Edit the file, remove the  
> 'end's and insert colons after the keywords which began those blocks,  
> run it through and... hey, whaddaya know, [16, 22, 28], first time  
> through. Looks like ol' Tony really \_was\_ talking out of his ass, eh?

You accomplished ABSOLUTELY nothing with your magic trick here, and you darn  
well know it. You in no way shape or form made the indent context work at  
all. All you did was figure out that a regular expression could add the word  
"end" to a block of data when told to. No one ever said that wasn't  
possible. That would be like saying that python can actually handle multi  
line lambdas if I took your same concept and pre-processed a file to take  
any multi line lambdas and convert them to a function which is called as a  
single line lambda. So are you now saying that anyone that claims the python  
engine doesn't handle multi-line lambdas is talking out of their ass?

If all you want is a preprocessor then it seems like you already have what  
you want and can be on your way to writing what you perceive as beautiful  
code immediately. Congrats and have at it, I'm not sure what more you would  
want at this point.

If you feel that you want to push this further into the core then again -  
have at it - many folks have suggested that forking and getting some ACTUAL  
working code in front of folks is the surest way to get things accomplished!  
I doubt that anyone would truly object if you implemented what you suggest,  
they simply are of the mindset that it won't work - prove them wrong, and  
not with a magic trick either.

Best of luck to you!

John W Higgins

> **···**
>
> On Mon, May 25, 2009 at 9:40 AM, J Haas \<Myrdred@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Caleb\_Clausen1](https://avatars.discourse-cdn.com/v4/letter/c/8dc957/32.png) [@Caleb\_Clausen1](https://rubytalk.org/u/Caleb_Clausen1)\
**Post date:** [25 May 2009 19:50 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/87 "2009-05-25T19:50:22Z")

</div>

It's certainly not impossible, as the script you posted shows. That  
script is a hack, however, since it doesn't lex its input properly and  
it will fail in obscure cases. I've written a proper implementation,  
based on my RubyLexer library.

Basically, it makes the end keyword optional. If you leave off the  
end, the preprocessor inserts an end for you at the next line indented  
at or below the level of indentation of the line which started the scope.

End is optional, so you can still write things like this:  
&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;do\_something  
&nbsp;&nbsp;end until done?  
(However, you'd better make damn sure you get the end indented to the  
right level!)

This script uses RubyLexer to extract a stream of tokens and modify  
it, then turn those tokens back into ruby code. Since RubyLexer is a  
complete stand-alone lexer, this should be a very thorough solution,  
free of insoluable little problems due to the script's inability to  
follow where comments and strings start and stop. (That said, I'm sure  
there will be some problems with it, as it's pretty raw code.)

As different programs have a variety of interpretations as to the  
width of a tab character, tabs for indentation are absolutely  
forbidden by endless.rb.

If you're interested, please see:

> <https://gist.github.com/coatl/117694>

> **···**
>
> On 5/25/09, J Haas \<Myrdred@gmail.com\> wrote:
> 
> > Now, having said all that: I do not \_know\_ that Tony's claim is false.  
> > As I said, I was surprised to be told that my proposal was impossible  
> > and I lack the theoretical background to prove otherwise. So if anyone  
> > out there agrees with Tony that Pythonic indentation in Ruby would not  
> > be merely ill-advised but \_impossible\_ I'd appreciate an example. Then  
> > I can stop wasting my time.

---

<div class="post-metadata">

**Author:** ![Joshua\_Ballanco](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@Joshua\_Ballanco](https://rubytalk.org/u/Joshua_Ballanco)\
**Post date:** [25 May 2009 22:43 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/88 "2009-05-25T22:43:36Z")

</div>

> As I said, I was surprised to be told that my proposal was impossible  
> and I lack the theoretical background to prove otherwise. So if anyone  
> out there agrees with Tony that Pythonic indentation in Ruby would not  
> be merely ill-advised but \_impossible\_ I'd appreciate an example. Then  
> I can stop wasting my time.

I was on a questionable connection at the time, so my original message may not have gotten to the mailing list:

\> cat impossible.rb

# This one can't be done in Pythonic style:

result = case ARGV[0]  
&nbsp;&nbsp;&nbsp;when /^\d\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer!"  
&nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word."  
&nbsp;&nbsp;&nbsp;end if ARGV[0]

puts result if result

Cheers,

Josh

> **···**
>
> On May 25, 2009, at 9:40 AM, J Haas wrote:

---

<div class="post-metadata">

**Author:** ![Reid\_Thompson1](https://avatars.discourse-cdn.com/v4/letter/r/6de8d8/32.png) [@Reid\_Thompson1](https://rubytalk.org/u/Reid_Thompson1)\
**Post date:** [27 May 2009 16:41 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/89 "2009-05-27T16:41:21Z")

</div>

I find this code less readable than the above original code with the  
'end's included

> **···**
>
> On Thu, May 28, 2009 at 01:35:11AM +0900, J Haas wrote:
> 
> > On May 22, 9:01 am, Roger Pack \<rogerpack2...@gmail.com\> wrote:  
> > \> Tony's point was that certain constructs, like case statements, won't be  
> > \> transformable into indentation only blocks. Does that make sense?
> > 
> > No, it doesn't, because I don't see why case statements are not  
> > transformable into indent-only blocks. I've \_done\_ them using the  
> > quick-and-dirty hacky script and they work just fine. (In cases like  
> > Joshua's impossible.rb I had to make a minor modification to the  
> > script to have it inject 'end ' rather than 'end\n', but it still  
> > worked fine.)
> > 
> > Code speaks louder than words, right? Here's some real-world code...  
> > it's application\_controller.rb from the AuthLogic example (http://  
> > github.com/binarylogic/authlogic\_example/tree):
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > &nbsp;&nbsp;helper :all  
> > &nbsp;&nbsp;helper\_method :current\_user\_session, :current\_user  
> > &nbsp;&nbsp;filter\_parameter\_logging :password, :password\_confirmation
> > 
> > &nbsp;&nbsp;private  
> > &nbsp;&nbsp;&nbsp;&nbsp;def current\_user\_session  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def require\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def require\_no\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > -----------------
> > 
> > Nothing particularly special about this code, right? Pretty standard  
> > Ruby, if a bit simple? 37 non-blank, non-comment lines, of which 9  
> > consist of the bare word "end". I defy anyone to tell me that the code  
> > would be less readable as this:
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > &nbsp;&nbsp;helper :all  
> > &nbsp;&nbsp;helper\_method :current\_user\_session, :current\_user  
> > &nbsp;&nbsp;filter\_parameter\_logging :password, :password\_confirmation
> > 
> > &nbsp;&nbsp;private  
> > &nbsp;&nbsp;&nbsp;&nbsp;def current\_user\_session:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def require\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def require\_no\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def store\_location:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil

---

<div class="post-metadata">

**Author:** ![Alex4](https://avatars.discourse-cdn.com/v4/letter/a/b487fb/32.png) [@Alex4](https://rubytalk.org/u/Alex4)\
**Post date:** [27 May 2009 16:44 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/90 "2009-05-27T16:44:44Z")

</div>

I'm just going to stick my head out for a second and say that I think the  
first code was more readable, with the end blocks. I LIKE being able to  
clearly see the end of a logical block. Yes, I can see the indentation  
change, but having a keyword end sections of code does a few things:  
1. It's easier for me to read, especially if I'm just skimming through  
2. It's easier to parse, and makes for cleaner parser code (to me, at least)

Come on guys, it's only 3 characters. Pythonic indentation is a big debate  
among programming languages, so can't we just accept it how it is and move  
on? Or, if someone really wants to change it, fork ruby and make the change  
yourself. Put up or shut up, is my (probably unwanted) opinion on the  
subject.

Alex

> **···**
>
> On Wed, May 27, 2009 at 12:35 PM, J Haas \<Myrdred@gmail.com\> wrote:
> 
> > On May 22, 9:01 am, Roger Pack \<rogerpack2...@gmail.com\> wrote:  
> > \> Tony's point was that certain constructs, like case statements, won't be  
> > \> transformable into indentation only blocks. Does that make sense?
> > 
> > No, it doesn't, because I don't see why case statements are not  
> > transformable into indent-only blocks. I've \_done\_ them using the  
> > quick-and-dirty hacky script and they work just fine. (In cases like  
> > Joshua's impossible.rb I had to make a minor modification to the  
> > script to have it inject 'end ' rather than 'end\n', but it still  
> > worked fine.)
> > 
> > Code speaks louder than words, right? Here's some real-world code...  
> > it's application\_controller.rb from the AuthLogic example (http://  
> > github.com/binarylogic/authlogic\_example/tree):
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > helper :all  
> > helper\_method :current\_user\_session, :current\_user  
> > filter\_parameter\_logging :password, :password\_confirmation
> > 
> > private  
> > &nbsp;&nbsp;&nbsp;def current\_user\_session  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def require\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def require\_no\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil  
> > &nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > -----------------
> > 
> > Nothing particularly special about this code, right? Pretty standard  
> > Ruby, if a bit simple? 37 non-blank, non-comment lines, of which 9  
> > consist of the bare word "end". I defy anyone to tell me that the code  
> > would be less readable as this:
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > helper :all  
> > helper\_method :current\_user\_session, :current\_user  
> > filter\_parameter\_logging :password, :password\_confirmation
> > 
> > private  
> > &nbsp;&nbsp;&nbsp;def current\_user\_session:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find
> > 
> > &nbsp;&nbsp;&nbsp;def current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record
> > 
> > &nbsp;&nbsp;&nbsp;def require\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;def require\_no\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;def store\_location:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri
> > 
> > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil

---

<div class="post-metadata">

**Author:** ![Roger\_Pack4](https://avatars.discourse-cdn.com/v4/letter/r/bb73d2/32.png) [@Roger\_Pack4](https://rubytalk.org/u/Roger_Pack4)\
**Post date:** [27 May 2009 22:42 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/91 "2009-05-27T22:42:42Z")

</div>

> No, it doesn't, because I don't see why case statements are not  
> transformable into indent-only blocks. I've \_done\_ them using the  
> quick-and-dirty hacky script and they work just fine. (In cases like  
> Joshua's impossible.rb I had to make a minor modification to the  
> script to have it inject 'end ' rather than 'end\n', but it still  
> worked fine.)

True I suppose case statements could be done using blocks.  
Note also that you don't "need" the ending : per line, either.

-=r

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Joshua\_Ballanco](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@Joshua\_Ballanco](https://rubytalk.org/u/Joshua_Ballanco)\
**Post date:** [28 May 2009 05:40 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/92 "2009-05-28T05:40:36Z")

</div>

> > Tony's point was that certain constructs, like case statements, won't be  
> > transformable into indentation only blocks. Does that make sense?
> 
> No, it doesn't, because I don't see why case statements are not  
> transformable into indent-only blocks. I've \_done\_ them using the  
> quick-and-dirty hacky script and they work just fine. (In cases like  
> Joshua's impossible.rb I had to make a minor modification to the  
> script to have it inject 'end ' rather than 'end\n', but it still  
> worked fine.)

Ok, but now you're beginning to see the edge cases that make this sort of transformation difficult on a global level. Specifically, how would you differentiate between these two cases using Pythonic indentation:

\> cat conditional\_case.rb  
result = case ARGV[0]  
&nbsp;&nbsp;&nbsp;when /^\d\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer"  
&nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word"  
&nbsp;&nbsp;&nbsp;end if ARGV[0]

puts result

\> cat case\_and\_conditional.rb  
result = case ARGV[0]  
&nbsp;&nbsp;&nbsp;when /^\d\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer"  
&nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word"  
&nbsp;&nbsp;&nbsp;end  
if ARGV[0]  
&nbsp;&nbsp;&nbsp;puts result  
end

Attaching a conditional to the end of a case statement (or any block, for that matter) is possible in Ruby because the block is just an expression, and the statement doesn't end until the newline. With your preprocessor, adding "end " when the indentation level decreases would yield the first form, but then how do I get the second form? I suppose I could both decrease the indentation level and leave a blank space, but then it seems like we're adding an awful lot of formatting rules just to have the code look nice and still function. On top of that, I think this makes things much less clear! Consider that in "Pythonic form" the above cases would become:

\> cat pythonic\_conditional\_case.rb  
result = case ARGV[0]:  
&nbsp;&nbsp;&nbsp;when /^\d\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer"  
&nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word"  
if ARGV[0]  
puts result

\> cat pythonic\_case\_and\_conditional.rb  
result = case ARGV[0]:  
&nbsp;&nbsp;&nbsp;when /^\d\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer"  
&nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word"

if ARGV[0]:  
&nbsp;&nbsp;&nbsp;puts result

Looking at those two pieces of code, is it clear that they do two different things? At the very least, I think that this sort of change to the syntax would have to be optional. This would, of course, mean that you're not getting rid of all of the "end"s in code, so then what's the point (other than to confuse matters of syntax even more)?

Let me also provide a counter-point. I'm currently using MacVim with the ruby-vim files and a coloring scheme which colors "def...end" pairs in yellow and other "case/if/do/etc...end" pairs in purple. This gives me a good way to quickly look at some code, and if I see that the "end" immediately preceding a "def" is purple, then I know I've forgotten and "end" somewhere in that function definition.

Finally, let me suggest a bit of a "wisdom of crowds" argument: if the advantages to significant whitespace were so unambiguously clear as you'd have us believe, then why do most languages not use it (even those developed before many of the advantages of advanced text editors/IDEs existed)?

- Josh

> **···**
>
> On May 27, 2009, at 9:35 AM, J Haas wrote:
> 
> > On May 22, 9:01 am, Roger Pack \<rogerpack2...@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Juan\_Zanos](https://avatars.discourse-cdn.com/v4/letter/j/4da419/32.png) [@Juan\_Zanos](https://rubytalk.org/u/Juan_Zanos)\
**Post date:** [28 May 2009 14:06 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/93 "2009-05-28T14:06:42Z")

</div>

As I've watched this debate unfold I've watched the stronger criticisms fall  
apart. The strongest type of criticism would be that it can't be done, or that  
it's too hard to be done. But the impossible examples seem to be defeated  
fairly easily. Moreover, the solutions are backward compatible to existing  
Ruby.

Now when I look at this latest example I see some ordinary code that's 44 lines  
long. With the pythonic scheme it looks like it's only 35 lines long. I find  
it difficult to convince myself that it's a good idea to make code 25% larger  
just to preserve some ends of dubious value.

I suppose I could try to come up with some nonsense argument that 'end' makes  
everything more readable. But that would just be prejudice. The pythonic  
example is trivially easy to read. It can't just be me. There seems to be no  
shortage of Python folk who have no problem. Objectively, the ends just take  
up a whole lot of space.

> **···**
>
> On May 27, 2009, at 12:35 PM, J Haas wrote:
> 
> > On May 22, 9:01 am, Roger Pack \<rogerpack2...@gmail.com\> wrote:
> > 
> > > Tony's point was that certain constructs, like case statements, won't be  
> > > transformable into indentation only blocks. Does that make sense?
> > 
> > No, it doesn't, because I don't see why case statements are not  
> > transformable into indent-only blocks. I've \_done\_ them using the  
> > quick-and-dirty hacky script and they work just fine. (In cases like  
> > Joshua's impossible.rb I had to make a minor modification to the  
> > script to have it inject 'end ' rather than 'end\n', but it still  
> > worked fine.)
> > 
> > Code speaks louder than words, right? Here's some real-world code...  
> > it's application\_controller.rb from the AuthLogic example (http://  
> > github.com/binarylogic/authlogic\_example/tree):
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > helper :all  
> > helper\_method :current\_user\_session, :current\_user
> > 
> > On May 27, 2009, at 12:35 PM, J Haas wrote:
> > 
> > > On May 22, 9:01 am, Roger Pack \<rogerpack2...@gmail.com\> wrote:
> > > 
> > > > Tony's point was that certain constructs, like case statements, won't be  
> > > > transformable into indentation only blocks. Does that make sense?
> > > 
> > > No, it doesn't, because I don't see why case statements are not  
> > > transformable into indent-only blocks. I've \_done\_ them using the  
> > > quick-and-dirty hacky script and they work just fine. (In cases like  
> > > Joshua's impossible.rb I had to make a minor modification to the  
> > > script to have it inject 'end ' rather than 'end\n', but it still  
> > > worked fine.)
> > > 
> > > Code speaks louder than words, right? Here's some real-world code...  
> > > it's application\_controller.rb from the AuthLogic example (http://  
> > > github.com/binarylogic/authlogic\_example/tree):
> > > 
> > > -----------------
> > > 
> > > # Filters added to this controller apply to all controllers in the  
> > > application.  
> > > # Likewise, all the methods added will be available for all  
> > > controllers.
> > > 
> > > class ApplicationController \< ActionController::Base  
> > > helper :all  
> > > helper\_method :current\_user\_session, :current\_user  
> > > filter\_parameter\_logging :password, :password\_confirmation
> > > 
> > > private  
> > > &nbsp;&nbsp;&nbsp;def current\_user\_session  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def current\_user  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > > current\_user\_session.record  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def require\_user  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def require\_no\_user  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def store\_location  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri  
> > > &nbsp;&nbsp;&nbsp;end
> > > 
> > > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil  
> > > &nbsp;&nbsp;&nbsp;end  
> > > end
> > > 
> > > -----------------
> > > 
> > > Nothing particularly special about this code, right? Pretty standard  
> > > Ruby, if a bit simple? 37 non-blank, non-comment lines, of which 9  
> > > consist of the bare word "end". I defy anyone to tell me that the code  
> > > would be less readable as this:
> > > 
> > > -----------------
> > > 
> > > # Filters added to this controller apply to all controllers in the  
> > > application.  
> > > # Likewise, all the methods added will be available for all  
> > > controllers.
> > > 
> > > class ApplicationController \< ActionController::Base  
> > > helper :all  
> > > helper\_method :current\_user\_session, :current\_user  
> > > filter\_parameter\_logging :password, :password\_confirmation
> > > 
> > > private  
> > > &nbsp;&nbsp;&nbsp;def current\_user\_session:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find
> > > 
> > > &nbsp;&nbsp;&nbsp;def current\_user:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > > current\_user\_session.record
> > > 
> > > &nbsp;&nbsp;&nbsp;def require\_user:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > > 
> > > &nbsp;&nbsp;&nbsp;def require\_no\_user:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > > 
> > > &nbsp;&nbsp;&nbsp;def store\_location:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri
> > > 
> > > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil
> > 
> > As this debate unfolds I've watched the stronger criticisms fall apart. The  
> > strongest type of criticism would be that it can't be done, or that it's too  
> > hard to do. But the impossible examples seem to be defeated fairly easily.  
> > Moreover, the solutions are backward compatible to existing Ruby.
> > 
> > Now when I look at this latest example I see some ordinary code that's 44 lines  
> > long. With the pythonic scheme it looks like it's only 35 lines long. I find  
> > it difficult to convince myself that it's a good idea to make code 25% larger  
> > just to preserve some ends of dubious value.
> > 
> > I suppose I could try to come up with some nonsense argument that 'end' makes  
> > everything more readable. But that would just be prejudice. It's trivially  
> > easy to read. It can't just be me. There seems to be no shortage of Python  
> > folk who have no problem either. Objectively, being forced to explicitly type  
> > 'end' all the time seems to takes up a whole lot of space.
> > 
> > filter\_parameter\_logging :password, :password\_confirmation
> > 
> > private  
> > &nbsp;&nbsp;&nbsp;def current\_user\_session  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def require\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def require\_no\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil  
> > &nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > -----------------
> > 
> > Nothing particularly special about this code, right? Pretty standard  
> > Ruby, if a bit simple? 37 non-blank, non-comment lines, of which 9  
> > consist of the bare word "end". I defy anyone to tell me that the code  
> > would be less readable as this:
> > 
> > -----------------
> > 
> > # Filters added to this controller apply to all controllers in the  
> > application.  
> > # Likewise, all the methods added will be available for all  
> > controllers.
> > 
> > class ApplicationController \< ActionController::Base  
> > helper :all  
> > helper\_method :current\_user\_session, :current\_user  
> > filter\_parameter\_logging :password, :password\_confirmation
> > 
> > private  
> > &nbsp;&nbsp;&nbsp;def current\_user\_session:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user\_session if defined?(@current\_user\_session)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user\_session = UserSession.find
> > 
> > &nbsp;&nbsp;&nbsp;def current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return @current\_user if defined?(@current\_user)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@current\_user = current\_user\_session &&  
> > current\_user\_session.record
> > 
> > &nbsp;&nbsp;&nbsp;def require\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged in to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to new\_user\_session\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;def require\_no\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if current\_user:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;store\_location  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flash[:notice] = "You must be logged out to access this page"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to account\_url  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false
> > 
> > &nbsp;&nbsp;&nbsp;def store\_location:  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = request.request\_uri
> > 
> > &nbsp;&nbsp;&nbsp;def redirect\_back\_or\_default(default):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect\_to(session[:return\_to] || default)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session[:return\_to] = nil

---

<div class="post-metadata">

**Author:** ![Juan\_Zanos](https://avatars.discourse-cdn.com/v4/letter/j/4da419/32.png) [@Juan\_Zanos](https://rubytalk.org/u/Juan_Zanos)\
**Post date:** [20 May 2009 21:23 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/94 "2009-05-20T21:23:06Z")

</div>

I'm saying that when all other factors are held constant more lines is  
less readable. Your arguments ignore that and only place value on  
editors and project management when the extra lines exist and  
not when they don't. That's not a level playing field.

Thinking about ways to reduce this overhead in the language is good.

> **···**
>
> On May 20, 2009, at 4:39 PM, Gregory Brown wrote:
> 
> > On Wed, May 20, 2009 at 4:32 PM, Juan Zanos \> \<juan\_zanos@talkhouse.com\> wrote:
> > 
> > > You want me to have even more files and spend even more time folding and  
> > > unfolding things. And you assume I use a crummy editor and there is a  
> > > better one that magically makes a surprising number of wasted lines  
> > > irrelevant. I think you accidentally illustrated that extra lines have a  
> > > cost.
> > 
> > I didn't accidentally illustrate anything. And everything has a  
> > cost. Why don't you list for yourself the cost of editing code with  
> > significant white space?  
> > Maybe for you, those costs are irrelevant. For me, the costs of ends  
> > in Ruby code are irrelevant.
> > 
> > But your point was about \*readability\* not maintainability. I don't  
> > think that good project organization is a 'cost' to readability.

---

<div class="post-metadata">

**Author:** ![Jorg\_W\_Mittag2](https://avatars.discourse-cdn.com/v4/letter/j/e79b87/32.png) [@Jorg\_W\_Mittag2](https://rubytalk.org/u/Jorg_W_Mittag2)\
**Post date:** [22 May 2009 13:10 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/95 "2009-05-22T13:10:08Z")

</div>

Juan Zanos wrote:

> **···**
>
> > On May 21, 2009, at 1:26 PM, Steven Arnold wrote:
> > 
> > > On May 21, 2009, at 8:06 AM, Roger Pack wrote:
> > > 
> > > > Interesting--it's been awhile since I used C...what would  
> > > > macros...essentially do? An example of them?
> > > 
> > > I was thinking more like Lisp macros. Check out:
> > > 
> > > &nbsp;&nbsp;&nbsp;[defmacro - The Nature of Lisp](http://www.defmacro.org/ramblings/lisp.html)
> > 
> > The Ant XML example is a bit ironic. Ant's creator regrets using  
> > XML. He believes that he should have used a scripting language  
> > instead. Take a look at Rake and you'll see a DSL that does what Ant  
> > does and more.
> 
> JDD actually not only regrets using XML for Ant, he eclusively uses  
> Rake now to build his Java projects. At least that's what I read,  
> anyway.
> 
> jwm

---

<div class="post-metadata">

**Author:** ![Bill\_Kelly](https://avatars.discourse-cdn.com/v4/letter/b/cc9497/32.png) [@Bill\_Kelly](https://rubytalk.org/u/Bill_Kelly)\
**Post date:** [24 May 2009 22:09 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/96 "2009-05-24T22:09:35Z")

</div>

> My concern is that you can mistakenly add 4 spaces instead of two, or vice versa, and get valid code (i.e. the parser does not see anything technically wrong) yet not have the code you really wanted.

That happened to us a couple times developing in  
Python. We were using spaces only (no tabs) ...  
but somehow some tab characters did occasionally  
sneak into a source file. (Possibly by copy/paste  
of code from a different editor--I was never sure  
how it happened.)

So the indentation looked fine to us in the editor  
(seeing two-column tabs), but was interpreted  
differently by Python (eight-column tabs), resulting  
in some baffling "it can't possibly be doing that!"  
moments while debugging.

These days, I have my editor set to highlight tab  
characters visually... 🙂

Regards,

Bill

> **···**
>
> From: "James Britt" \<james.britt@gmail.com\>

---

<div class="post-metadata">

**Author:** ![David\_Masover](https://avatars.discourse-cdn.com/v4/letter/d/50afbb/32.png) [@David\_Masover](https://rubytalk.org/u/David_Masover)\
**Post date:** [25 May 2009 21:19 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/97 "2009-05-25T21:19:15Z")

</div>

You can get the same problem by misplacing a bracket or a paren. The only  
difference I see is that the indentation is a lot more visibly obvious.

> **···**
>
> On Sunday 24 May 2009 03:42:19 pm James Britt wrote:
> 
> > My concern is that you can mistakenly add 4 spaces instead of two, or  
> > vice versa, and get valid code (i.e. the parser does not see anything  
> > technically wrong) yet not have the code you really wanted.

---

<div class="post-metadata">

**Author:** ![Caleb\_Clausen1](https://avatars.discourse-cdn.com/v4/letter/c/8dc957/32.png) [@Caleb\_Clausen1](https://rubytalk.org/u/Caleb_Clausen1)\
**Post date:** [26 May 2009 02:07 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/98 "2009-05-26T02:07:54Z")

</div>

Yes, and it's this very sort of case that led me to make end optional  
rather than forbidden in endless.rb. Clearly, some things can't be  
expressed just in pythonish syntax, so you have to be able to drop  
back to ruby mode. The need for more tokens on the same line after the  
end is sufficiently rare that I don't think it detracts from the  
overall effect; almost all ends can still be eliminated.

Actually, I think pyrb.rb also will tolerate this example as well; you  
just leave off the colon and it doesn't expect to create an end for  
you for that statement. Looks like it's missing the 'when' special  
case, but for this example, that doesn't matter, since you have the  
whens more indented anyway.

> **···**
>
> On 5/25/09, Joshua Ballanco \<jballanc@gmail.com\> wrote:
> 
> > I was on a questionable connection at the time, so my original message  
> > may not have gotten to the mailing list:
> > 
> > \> cat impossible.rb
> > 
> > # This one can't be done in Pythonic style:
> > 
> > result = case ARGV[0]  
> > &nbsp;&nbsp;&nbsp;when /^\d\*$/  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's an integer!"  
> > &nbsp;&nbsp;&nbsp;when /^[A-Za-z]\*$/  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That looks like a word..."  
> > &nbsp;&nbsp;&nbsp;else  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"That's not an integer or a word."  
> > &nbsp;&nbsp;&nbsp;end if ARGV[0]
> > 
> > puts result if result

---

<div class="post-metadata">

**Author:** ![Roger\_Pack4](https://avatars.discourse-cdn.com/v4/letter/r/bb73d2/32.png) [@Roger\_Pack4](https://rubytalk.org/u/Roger_Pack4)\
**Post date:** [27 May 2009 11:37 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/99 "2009-05-27T11:37:52Z")

</div>

> This script uses RubyLexer to extract a stream of tokens and modify  
> it, then turn those tokens back into ruby code. Since RubyLexer is a  
> complete stand-alone lexer, this should be a very thorough solution,  
> free of insoluable little problems due to the script's inability to  
> follow where comments and strings start and stop. (That said, I'm sure  
> there will be some problems with it, as it's pretty raw code.)
> 
> As different programs have a variety of interpretations as to the  
> width of a tab character, tabs for indentation are absolutely  
> forbidden by endless.rb.
> 
> If you're interested, please see:  
> [endless.rb · GitHub](http://gist.github.com/117694)

Could you post us a few examples of what code formatted this way looks  
like (or must look like)? I assume it handles here documents well?

The italics part of that gist is somewhat hard to read 🙂

@Michael:  
I don't think having "either or" syntax would be such a terrible thing  
in terms of team re-use or resources--you should be able to convert the  
code back and forth at will (a la ruby2ruby, parsetree [rubylexer has a  
parsetree compatibility mode] etc.)  
Cheers!  
-=r

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Eleanor\_McHugh](https://avatars.discourse-cdn.com/v4/letter/e/8c91f0/32.png) [@Eleanor\_McHugh](https://rubytalk.org/u/Eleanor_McHugh)\
**Post date:** [27 May 2009 17:10 UTC](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479/100 "2009-05-27T17:10:02Z")

</div>

+1 - the significant white space is one of several reasons I've never managed to get comfy with python.

Personally I like 'end' because it makes it explicitly clear that the programmer's intent was to end a block at that point, and I've wasted enough of my life tracking down nesting errors not to want to give up that extra bit of insight. If other people feel differently, well it's there code and they're free to do as they please with it so long as I'm not expected to maintain it.

Ellie

Eleanor McHugh  
Games With Brains  
[http://slides.games-with-brains.net](http://slides.games-with-brains.net)

> **···**
>
> On 27 May 2009, at 17:41, Reid Thompson wrote:
> 
> > I find this code less readable than the above original code with the  
> > 'end's included
> 
> ----  
> raise ArgumentError unless @reality.responds\_to? :reason

[Previous page](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479.md?page=4)

[Next page](https://rubytalk.org/t/pythonic-indentation-or-beating-a-dead-horse/53479.md?page=6)
