Pythonic indentation (or: beating a dead horse)

J

James Britt

Reid said:
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
 
B

Bill Kelly

From: "James Britt said:
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
 
J

J Haas

Well, everything else aside: if you can't present your ideas or engage in
discussion without being an asshole, you're going to have a hard time
getting people to listen to you. I've been trying to give constructive
criticism, but when you come back at me with personal attacks I'm left to
wonder why I should even bother.

It looks like another recap will be necessary.

In the beginning, I began a thread containing a proposal to implement
Python-style syntactically significant indentation in Ruby (this
proposal, I might add, was entirely optional, and would leave in place
a system which would support _either_ indentation-delimited code
blocks or keyword-delimited code blocks.) At the time I posted it, I
expected opposition. I expected to be told that the requirement to
fill the code base 1/6th full of 'ends' actually _improved_
readability, and I was not disappointed. I expected ridiculous
strawman arguments involvingremovalofallspacesfromEnglish, and I was
not disappointed. I expected to have my motives questioned, with
insinuations that I secretly hated Ruby, and I was not disappointed.
Furthermore, I was prepared to ignore every one of these arguments, as
every one is fallacious. I trust in rational people to see the fallacy
behind each and will not do the fallacies the dignity of treating them
as though they were serious arguments, worthy of respectful rebuttal.

What I did _not_ expect to hear, however, was a claim that my proposal
was actually _impossible_.
You can have the Pythonic indent syntax or a purely expression
based grammar with multi-line blocks. You can't have both.

This took me by surprise, and for all I know, it might well be true.
As you may have surmised, I do not claim syntactical parser design or
theory among my areas of expertise. For all I know, there was some
reason I wasn't aware of why what I proposed was impossible, even in
theory. And yet, I know I'd seen a script awhile ago, which I thought
I had saved on an old hard drive somewhere, which could actually _do_
Pythonic indentation in Ruby. And so I asked you for clarification.
I'm having a hard time following why. Can you provide an example of a
Ruby snippet that couldn't be done with scoping defined by
indentation?

That's all I needed. If there were a theoretical reason why Python-
style indentation were incompatible with some fundamental concept in
Ruby, it should be easy to provide an example of a Ruby construct
which would be impossible to parse without the use of 'end' or some
other keyword as a block delimiter. That's all it would take. That's
all I asked for. Did I get it?
A multi-line block returning a value, e.g.
foo = somemethod do |arg1, arg2, arg3|
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3
end

Or for that matter, a multi-line lambda:

foo = lambda do |arg1, arg2, arg3|
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3
end

I looked at these and was flabbergasted. In what way were these at all
incompatible with syntactic indentation? What would be impossible to
parse about this?

foo = somemethod do |arg1, arg2, arg3|:
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3

Or this?

foo = lambda do |arg1, arg2, arg3|:
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3

How on Earth did these examples meet the test of being incompatible
with Python-style indentation? You provided a number of other examples
that similarly baffled me as to how they were supposed to support your
thesis. It was at this point that I began to lose patience with you
and suspect that you might be talking out of your ass.
You keep on saying this, yet I have not seen one example of code that
demonstrates that using dedent couldn't work. Basically, we're looking
for some code which, if you removed the all ends, a script following
simple deterministic rules would not be able to unambigiously decide
where to put them back.

Your response was:
Okay, you just want an example I guess.

(jh: what was your first clue?)
Here is an example Ruby program:

foo = [1,2,3]
x = foo.map do |n|
n += 1
n *= 2
end
result = case x
when Array
x.map! do |n|
n *= 3
n += 4
end
when NilClass
x
end
result = if result.size > 10
result[0..2]
else
result
end
p result

The output of this program is:

[16, 22, 28]

Show me how you would parse the equivalent program in an
indentation-sensitive Ruby, e.g.:

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?

I did not trouble to hide my lack of respect in my response conveying
that your proof of impossibility was false on its face. However, I do
not think that anything at all in that post could have been construed
as a "personal attack". If you disagree, please point out an example.

Your next response to me was full of backpedaling falsehoods, such as:
My claims were it's impossible with a Pythonic lexer and a backing context
free grammar.

And this:
I certainly didn't claim that if you throw enough regexes at
the problem it won't go away.

Just what do you think a regular expression engine is? Hint: it's a
parser. If application of regular expressions can solve a problem, the
problem is not insoluble by a parser.
Well great! I'm not really sure how that script works

"...but it must be magic, since it does the impossible!"
However, what you have there is a marked departure from how Python actually works.

I know I already responded to this gem with mockery, but not nearly as
much as it deserves.
But if you're happy with it, great. Go for it and see how popular you can
make it.

I don't care about being popular. If I did, I wouldn't be such an
asshole.

And then, without even waiting for a reply:
you're being a right c--t

This is, as far as I know, the first and only personal attack in this
thread, unless you want to count my self-description as an asshole to
be a personal attack. But either way, never fear, Tony, your own
precious person has yet to be attacked.

And this brings us to your most recent post in this thread.
Well, everything else aside: if you can't present your ideas or engage in
discussion without being an asshole, you're going to have a hard time
getting people to listen to you.

No, Tony, that's wrong. If I can't present my ideas or engage in
discussion without being an asshole, I'm going to have a hard time
getting people like _you_ to listen to me. People who are logical,
programmers who want the best possible language with the greatest
flexibility and expressiveness, will know that _ad_hominem_ is a
fallacy and will look to the arguments, not to the person making them.
I've been trying to give constructive
criticism, but when you come back at me with personal attacks I'm left to
wonder why I should even bother.

And now we reach the present. Tony, _what_ personal attacks? Please
cite them. Your relief at being able to use an alleged personal attack
as a fig leaf to escape your obligation to back up your claims is
palpable. An honorable person would either substantiate the claim or
retract it, rather than running and hiding and pretending to hurt
feelings.

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.
 
D

David Masover

You are proposing a Rube Goldberg contraption whereby the scanner would
require some degree of grammatical awareness. This is a complex solution.
The minor flaw is that you don't like "end" statements. Is the minor flaw
of having repeated end statements really worth the level of complexity the
solution would require?

If we're admitting that a parser is possible, but would only be complex, I
would say yes, it's worth it.

Ruby itself is based on the idea that the computer should work for you, not
the other way around. The language should be made simpler for a human to
understand and work with, even if it makes the implementation more complex and
slower. My understanding is, this is the founding principle of Ruby -- the
whole reason it was invented in the first place.

Of course, the more important question is whether this can be done in such a
way that is either wholly backwards compatible, or which doesn't irritate
people who like Ruby's current syntax?

The social aspect seems to be the larger issue, here.
 
J

John W Higgins

[Note: parts of this message were removed to make it a legal post.]


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
 
C

Caleb Clausen

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.

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:
begin
do_something
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:
http://gist.github.com/117694
 
D

David Masover

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.

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.
 
J

Joshua Ballanco

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]
when /^\d*$/
"That's an integer!"
when /^[A-Za-z]*$/
"That looks like a word..."
else
"That's not an integer or a word."
end if ARGV[0]

puts result if result


Cheers,

Josh
 
J

James Britt

David said:
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.

Interesting. I've had an incorrect number of braces and parens in the
past, and don't think it ever made for well-formed executable ruby. I
always got a parsing error.

It seems like a much harder mistake to make then taping the space key or
back space key a few too more or less times. (That is, a mistake that
still leaves the code perfectly runnable by the interpreter, but with
different semantics than intended.)

Also, mismatched brackets or do/ends are very easy to spot; I tell vim
to auto-format, and the borked code alignment and incorrect syntax
coloring shows me right away where the error is.

I'm unclear as to whether you can have accurate auto-formatting with
significant indentation (e.g., ggVG=).

--
James Britt

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development
 
C

Caleb Clausen

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]
when /^\d*$/
"That's an integer!"
when /^[A-Za-z]*$/
"That looks like a word..."
else
"That's not an integer or a word."
end if ARGV[0]

puts result if result

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.
 
M

Michael Bruschkewitz

David Masover said:
On Wednesday 20 May 2009 05:28:34 pm Tony Arcieri wrote:

The social aspect seems to be the larger issue, here.

This is pointing to the right direction.
But it depends on your particular semantic of "social".

(1) It would not only be a beer-table issue.
(Although many resources are always useless wasted for holy wars.)

It would probably spoil team projects and code reuse.
Given a team where one developer is familiar to pythonesque insertion.
Even if he is not one of these talibanesque people, he would probably use
this technique somewhere in his scripts.
Even if it's explicitely forbidden in the project, danger is, it would be
used unintentionally.
When this code is reused, other people which are not familiar to pythonesque
insertion may be trapped.
Maybe when trying to adapt the code, maybe by some automatic beautifying by
the editor, maybe when forced to debug this code.
This would possibly waste hours by hours while timelines fly by.

As OPoster unintentionally demonstrated in OP, some people aren't even able
to format postings in NG's properly.
(As I get caught already in this trap too, I rely on capabilities of modern
news_readers_.)

So, it would effectively split Rubyists into two fractions. Those, who use
PyI and those who don't.
We used Ruby for writing test scripts for safety related software. PyI would
have been a serious issue against using Ruby.
For not breaking existing code it would be necessary to be explicitely
allowed by a special switch, not to be allowed by default. This would limit
number of users.
(Maybe it is possible to implement it as a gem? This would change the
picture completely.)

(2) Further, resources needed for a clean implementation and maintenance of
PyI could be used for more urgent issues. (IMHO)
For example (I currently do not know the kernel of current Ruby-versions nor
all current extensions because I'm still forced to use 1.6.8 or 1.8.6 for
compatibility reasons.):
I would like to wait for generic Events in the central loop, not only for
file descriptors and timeouts. (Limitations of "C-Lib"-select()).
Independence of OS-platform should be increased in the kernel.
Real-Time capabilities would be nice.
There are, fore sure, many issues on the wish-list for future Ruby kernels
which have a higher priority.

(3) Isn't there a list where such issues are discussed? I think, Ruby is
mature enough to establish such a process.
For further development, it should be tried to implement a standard like
this one for "C" or "C++".
IMO, Ruby is so widely used there is more than enough reason for doing so.

Best Regards,
Michael B.
 
R

Roger Pack

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:
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
 
S

sunnia

Or maybe some variation on Lisp's superparenthesis?

http://www.gavilan.edu/csis/languages/parentheses.html

The Judicial System in Islam : Its Legal Basis and Islam Ruling
Please forgive us for any disturbance, but we have an important
subject to address to you regarding FAITH, and we Don’t intend to
overload your email with unnecessary messages…

The Judicial System in Islam : Its Legal Basis and Islam Ruling

By The Editorial Team of Dr. Abdurrahman al-Muala (translated by
islamtoday.com)


Defining the Judicial System and its Legal basis

The judicial system in Islam is a system for deciding between people
in litigation with the aim of settling their disputes in accordance
with the injunctions of the Divine Law, injunctions that are taken
from the Quran and Sunnah.

All of the Messengers of God (may God praise them all) acted as
judges. God says:

“And remember David and Solomon, when they gave judgment concerning
the field when people’s sheep had browsed therein at night, and We
were witness to their judgment. And We made Solomon to understand the
case. And to each of them We gave good judgment and knowledge.” (Quran
21:78-79)
God also says:

“O David, verily we have placed you as a successor on Earth, so judge
between people in truth, and do not follow your desires for it will
mislead you from the path of God. Verily, those who stray from the
path of God have a severe punishment because they forgot the day of
reckoning.” (Quran 38:26)

Prophet Muhammad, who came with the final and eternal Message, was
ordered by God to pass judgment in disputes just as he was ordered to
spread the word of God and call people to Islam. This is mentioned in
the Quran in a number of places. God says, for instance:

“So judge (O Muhammad) between them by what God has revealed and do
not follow their vain desires, but beware of them lest they turn you
away from some of what God has sent down to you.” (Quran 5:49)

God also says:

“…And if you judge (O Muhammad), judge between them with justice.
Verily, God loves those who act justly.” (Quran 5:42)

And He says:

“But no, by your Lord, they shall have no faith until they make you (O
Muhammad) judge in all their disputes and find in themselves no
resistance against your decisions and accept them with full
submission.” (Quran 4:65)

The Sunnah also provides for the legal basis of the Islamic judicial
system. It is related by Amr b. al-Aas that the Prophet said:

“If a judge gives a judgment using his best judgment and is correct,
then he receives a double reward (from God). If he uses his best
judgment but makes a mistake, then he receives a single
reward.” (Ahmed)

God’s Messenger said:

“You should not wish to be like other people, except in two cases: a
man who God has given wealth and he spends it on Truth and another who
God has granted wisdom and he gives verdicts on its basis and teaches
others.” (Saheeh Al-Bukhari, Saheeh Muslim)

Many scholars have related to us that there is consensus among Muslims
on the legal status of the judicial system in Islam. Ibn Qudamah says:

“The Muslims are unanimously agreed that a judicial system must be
established for the people.”
The Islamic Ruling Concerning the Judiciary

The jurists agree that the duties of the judge are an obligation that
must be carried out by society. If some members of society carry out
this duty, it is sufficient for everyone. If, on the other hand,
everyone neglects it, then everyone in society is sinful.

The proof that these duties are obligatory comes from the Quran:

“O you who believe! Stand out firmly for justice...” (Quran 4:135)

It is only necessary for a small number of individuals to perform
judicial duties since judicial concerns come under the broad duty of
enjoining what is right and forbidding what is wrong. It is not
obligatory for every individual to carry out this duty as long as some
people are doing so.

The affairs of the people will not be correct and upright without a
judicial system. It is, consequently, obligatory for one to exist,
just like it is necessary to have a military. Imam Ahmad, one of the
greatest and most well-known scholars of Islam said:

“People have to have a judicial authority or their rights will
disappear.”

The duties of the judiciary include enjoining what is right, helping
the oppressed, securing people’s rights, and keeping oppressive
behavior in check. None of these duties can be performed without the
appointment of a judiciary.

A judicial system is a necessity for the prosperity and development of
nations. It is needed to secure human happiness, protect the rights of
the oppressed, and restrain the oppressor. It is the way to resolve
disputes and ensure human rights. It facilitates enjoining what is
right, forbidding what is wrong, and curbing immoral behavior. In this
way, a just social order can be enjoyed by all sectors of society, and
every individual can feel secure in his life, property, honor, and
liberty. In this environment, nations can progress, civilization can
be achieved, and people are free to pursue what will better them both
spiritually and materially.




———————————-


For more information about Islam

http://english.islamway.com/

http://www.islamhouse.com/

http://www.discoverislam.com/

http://www.islambasics.com/index.php

http://english.islamway.com/

http://www.islamtoday.net/english/

http://www.islamweb.net/ver2/MainPage/indexe.php

http://www.sultan.org/

http://www.islamonline.net/

Contact Us At

(e-mail address removed)
 
J

J Haas

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
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end

def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record
end

def require_user
unless current_user
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end

def require_no_user
if current_user
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end

def store_location
session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
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
def current_user_session:
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find

def current_user:
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record

def require_user:
unless current_user:
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false

def require_no_user:
if current_user:
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false

def store_location:
session[:return_to] = request.request_uri

def redirect_back_or_default(default):
redirect_to(session[:return_to] || default)
session[:return_to] = nil
 
R

Reid Thompson

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
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end

def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record
end

def require_user
unless current_user
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end

def require_no_user
if current_user
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end

def store_location
session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
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
def current_user_session:
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find

def current_user:
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record

def require_user:
unless current_user:
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false

def require_no_user:
if current_user:
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false

def store_location:
session[:return_to] = request.request_uri

def redirect_back_or_default(default):
redirect_to(session[:return_to] || default)
session[:return_to] = nil
I find this code less readable than the above original code with the
'end's included
 
A

Alex

[Note: parts of this message were removed to make it a legal post.]

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

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
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end

def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record
end

def require_user
unless current_user
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false
end
end

def require_no_user
if current_user
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false
end
end

def store_location
session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
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
def current_user_session:
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find

def current_user:
return @current_user if defined?(@current_user)
@current_user = current_user_session &&
current_user_session.record

def require_user:
unless current_user:
store_location
flash[:notice] = "You must be logged in to access this page"
redirect_to new_user_session_url
return false

def require_no_user:
if current_user:
store_location
flash[:notice] = "You must be logged out to access this page"
redirect_to account_url
return false

def store_location:
session[:return_to] = request.request_uri

def redirect_back_or_default(default):
redirect_to(session[:return_to] || default)
session[:return_to] = nil
 
E

Eleanor McHugh

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

+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
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

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

I like the symmetry that end statements give to the code. It feels more...
balanced or something.
 
R

Roger Pack

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
 
C

Caleb Clausen

Could you post us a few examples of what code formatted this way looks

Oops, I should have done that when I posted before. Thanks for the reminder.

#so you can leave off the end of a method
def a
c
d

#or anything else that requires an end
for i in 1..10
p i
pp i

#else and other keywords which start a subclause
#of a statement don't cause an end if outdented at the same level
#as the if which controls them.
if a
b
else
c

#if you actually need an end, that's allowed too
#(if not further outdented than the line that started the statement)
result = case ARGV[0]
when /^\d*$/
p "That's an integer!"
when /^[A-Za-z]*$/
p "That's a word!"
else
p "That's something that's not an integer or a word..."
end if ARGV[0]

#you can explicitly end just the last scope of something deeply nested.
class A
class B
class C
module D
foo
end #actually 4 ends
like (or must look like)? I assume it handles here documents well?

It _should_, since rubylexer does. I didn't test them explicitly. Here documents
appear like one giant string; the indentation levels of all lines
inside strings are ignored. (There might be some very obscure
here-document related bugs left in rubylexer which would bite you in
endless.rb as well, tho I can't think of any right now. Most cases
should work. Here documents are weird.)
The italics part of that gist is somewhat hard to read :)

I do apologize. It seems ok to me... What's hard about it? (You can
always just hit the link for the raw view.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top