How to adopt "Python Style" indentation for Ruby


#1

Obviously based on the earlier thread. I think this is actually an
utterly terrible idea. Haven’t you heard that song by Loverboy? “Pig
and elephant DNA just don’t mix”? But I think the implementation
would be fascinating.

What would it take to write a Ruby pre-processor which parsed Ruby
written in a Pythonic style and turned it into actual valid Ruby? Or
even a Ruby library like Xavier’s Perl example, which allows you to
code Ruby as if it were Python after just requiring the library? The
original post’s main argument was that indentation is a stable,
consistent shorthand for Ruby’s end statements. If all you’re looking
to do is use tabs as syntactic sugar, then it should be pretty easy to
just write something which knows how to translate a sequence of tabs
in and tabs out into a series of end statements at the end.

Is this only doable in Perl, because Perl has source filtering? Would
you have to encase the Pythonic “Ruby” in a string and then run that
string through a processor after the fact, or could it “just work”
without any obvious prep on the user’s part? If you did it as a
string, it should be as easy as counting tabs. But source filtering,
that sounds like the better way.


Giles B.

I’m running a time management experiment: I’m only checking e-mail
twice per day, at 11am and 5pm. If you need to get in touch quicker
than that, call me on my cell.

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org


#2

On Mon, May 21, 2007 at 03:53:25PM +0900, Giles B. wrote:

What would it take to write a Ruby pre-processor which parsed Ruby
written in a Pythonic style and turned it into actual valid Ruby? Or
even a Ruby library like Xavier’s Perl example, which allows you to
code Ruby as if it were Python after just requiring the library? The
original post’s main argument was that indentation is a stable,
consistent shorthand for Ruby’s end statements. If all you’re looking
to do is use tabs as syntactic sugar, then it should be pretty easy to
just write something which knows how to translate a sequence of tabs
in and tabs out into a series of end statements at the end.

Actually, I’d happily settle for something simpler: a pretty-printer
which
just reads (normal) Ruby and re-outputs it with standard indentation.

This would immediately solve the problem of “where did I miss out an
‘end’
statement?” - you’d just pipe it into this utility and inspect. In the
past
I’ve had to resort to binary chops to solve this: copy source.rb to x.rb
and
remove chunks of method definitions until I find the offending one. This
is
painful.

As an alternative: the existing Ruby parser could be modified to spit
out a
warning whenever it sees non-standard nesting, e.g. "end at line
doesn’t
align with start of block/method at line ". It only need do this for
an
‘end’ which is at the start of a line.

Regards,

Brian.


#3

On 5/21/07, Brian C. removed_email_address@domain.invalid wrote:

On Mon, May 21, 2007 at 03:53:25PM +0900, Giles B. wrote:

What would it take to write a Ruby pre-processor which parsed Ruby
written in a Pythonic style and turned it into actual valid Ruby?

Actually, I’d happily settle for something simpler: a pretty-printer which
just reads (normal) Ruby and re-outputs it with standard indentation.

This would immediately solve the problem of “where did I miss out an ‘end’
statement?” -

In vim, I find that ggVG= does that job well enough.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/


#4

On May 21, 3:32 am, Brian C. removed_email_address@domain.invalid wrote:

warning whenever it sees non-standard nesting, e.g. "end at line doesn’t
align with start of block/method at line ". It only need do this for an
‘end’ which is at the start of a line.

Regards,

Brian.

I use Arachono Ruby IDE. Its editor has a feature whereby I can select
a number of lines to comment out or uncomment the lines. This makes
finding the missing end fairly easier.

I find python indentation much harder to read. For my use, I rather
stick with the "end"s.


#5

Actually, I’d happily settle for something simpler: a pretty-printer which
just reads (normal) Ruby and re-outputs it with standard indentation.

This already exists, and was written by somebody on this list, but I’m
having a hard time googling it.


Giles B.

I’m running a time management experiment: I’m only checking e-mail
twice per day, at 11am and 5pm. If you need to get in touch quicker
than that, call me on my cell.

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org


#6

Giles B. wrote:

consistent shorthand for Ruby’s end statements. If all you’re looking

Another version of pyrb.rb has been written that allows proper
multilevel dedenting and removes the requirement for a separate
.pyrb file

You can now do in test.rb

#####################################
require ‘pyrb.rb’
END

def foo:
[1,2,3,4].each do |i|:
puts i
[1,2,3,4].each do |j|:
puts i
if i == 2 :
puts “foo”
else:
puts “bar”

foo
#####################################

http://xtargets.com/snippets/posts/show/68

Disclaimer : The above library in no way whatsoever should be taken as a
suggestion that the author thinks Python is better than Ruby or
vice versa. All suggestions to that effect are purely fictional and
the author is in no way responsible for flame wars that may ensue
from use or misuse of the library. The author wrote the library
because it could be done and for no other reason.


#7

Obviously based on the earlier thread. I think this is actually an
utterly terrible idea. Haven’t you heard that song by Loverboy? “Pig
and elephant DNA just don’t mix”? But I think the implementation
would be fascinating.

What would it take to write a Ruby pre-processor which parsed Ruby
written in a Pythonic style and turned it into actual valid Ruby? Or

Another version of pyrb.rb has been written that allows proper
multilevel dedenting and removes the requirement for a separate
.pyrb file

This is absurdly cool. How does it work?

Oh I get it:

The trick to the new version is to use the END keyword
to block the Ruby scanner and then reload the current file after
doing the preprocessing.

That’s awesome! Sick and wrong in the best possible way. And simple!


Giles B.

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org


#8

On May 29, 3:50 pm, Brad P. removed_email_address@domain.invalid wrote:

Sick, wrong and simple but unfortunately not my idea. There is a library
hanging around called hyphen-ruby which showed me the dark path.

B

Actually you can do this without even using the END. pyrb.rb can
exit the process so it will never reach the rest of the original file.

T.


#9

Sick, wrong and simple but unfortunately not my idea. There is a library
hanging around called hyphen-ruby which showed me the dark path.

B


#10

On May 29, 7:37 pm, Trans removed_email_address@domain.invalid wrote:

Actually you can do this without even using the END. pyrb.rb can
exit the process so it will never reach the rest of the original file.

But then again, why bother? Just make a new executable called
‘pyruby’. And use that to run your .pyrb scripts.

T.


#11

Trans wrote:

B

Actually you can do this without even using the END. pyrb.rb can
exit the process so it will never reach the rest of the original file.

T.

I don’t think that will work. I believe that Ruby will syntax check the
entire file before trying to execute any of it.


#12

On May 30, 1:00 am, Brad P. removed_email_address@domain.invalid wrote:

Actually you can do this without even using the END. pyrb.rb can
exit the process so it will never reach the rest of the original file.

T.

I don’t think that will work. I believe that Ruby will syntax check the
entire file before trying to execute any of it.

Ah, right. Did something like this myself once but I had overlooked
the fact that my variant code still passed for valid ruby. In any
case, using a separate ‘pyruby’ runner would be the best way
regardless.

T.


#13

Dnia 29-05-2007 o 18:50:16 Brad P. removed_email_address@domain.invalid
napisał(a):

Giles B. wrote:
What would it take to write a Ruby pre-processor which parsed Ruby
written in a Pythonic style and turned it into actual valid Ruby?

It is already written

http://lazibi.rubyforge.org/


#14

bbiker wrote:

in and tabs out into a series of end statements at the end.
warning whenever it sees non-standard nesting, e.g. "end at line doesn’t

I find python indentation much harder to read. For my use, I rather
stick with the "end"s.

I’ve tried posting several times without success … here again.

http://xtargets.com/snippets/posts/show/68

shows a partial solution to your challenge by overloading require. It is
a quick hack but shows you how to write your own pre-processor. The
new require checks to find files of type .pyrb and then coverts them
to .rb files before loading them.


#15

Rick DeNatale wrote:

Why do I get the impression that this thread is trying to develop a
new language called FrankenRuPy?

Now, now! It’s just a sweet little creation. It couldn’t hurt anyone
could it ?

B


#16

On 5/22/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

       @components.each do |row|
   end
                       pre do :

start with:
end
end
end
end

And with the judicious use of {} vs. do end there are other
alternatives which may suit individual tastes depending on how tightly
you like to see the code:

table do
@components.each do |row|
tr do
row.each do |col|
td {pre {text col}
end
end
end
end

or the ultra tight:

table {@components.each {|row| tr {row.each {|col| td {pre {text
col}}}}}

or if you aren’t religious about reserving brackets for one-line
blocks (I’m not):

table {
@components.each { |row|
tr {
row.each { |col|
td {pre {text col}
}
}
}
}

Or anywhere in-between.

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/


#17

What interests me about this thread is that, if you wish,
you can transparently add your own dialect to ruby by overloading
require. I’ve done the same thing before to load ERB files as if
they were real ruby files on the path. I jumped in at the challenge
of the OP as to whether transparent preprocessing is possible. The fact
that it is and so simply is a nice sign of the power of the ruby language.

As the OP in this thread, but not the one it spawned from, I just
wanted to turn the question from whether or not Ruby should be Python
to how to make Ruby Python if one so chose. I wouldn’t really do
it myself, but the question of how is a pretty interesting question
(and also one which has less risk of generating flame wars).

A few months back, during the Fizzbuzz craze, I saw a Fizzbuzz solver
which worked by defining a algorithm in Haskell which ran in a Haskell
interpreter which ran inside a Lisp interpreter which ran inside
another Lisp interpreter which was written in Ruby. Sometimes the
question of how to do something is interesting for its own sake,
whether the thing is worth doing or not.


Giles B.

I’m running a time management experiment: I’m only checking e-mail
twice per day, at 11am and 5pm. If you need to get in touch quicker
than that, call me on my cell.

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org


#18

M. Edward (Ed) Borasky wrote:

But I want a blue bike shed next to my nuclear power plant.

Coming soon from the Pragmatic Programmers: “What Color is Your Bike
Shed?” (Chapter 1: Why Ruby Syntax Sucks; previews are available on
ruby-talk.)

confusing to me as Perl’s “$hash{‘key’}” referring to an entry in
“%hash” vs. another variable entirely called “$hash”.

I can understand that being confusing at first, if you’ve never used an
expression-based language, but once you have seen code in which the
argument is evaluated from some nontrivial expression (or called from
some other class method), you should find it not at all strange, but
rather like an old friend.

attr_accessor(*File.read(“attr_list”).split)

It starts getting confusing again when you have to remember that the
alias keyword doesn’t work this way (but Module#alias_method does).


#19

On 5/22/07, Brad P. removed_email_address@domain.invalid wrote:

that it is and so simply is a nice sign of the power of the ruby language.
Agreed. Indentation vs. other ways of delimiting code blocks is just
a surface issue. For the most part, it is just a preference thing.

The lack of a real lambda (and its verbose syntax compared to ruby
blocks) in python is a much bigger issue. I still think python’s
crippling of the lambda has to do with the indentation thing. The way
they did it, indented code blocks (“suites”) are only part of
statements (not more generic expressions). Since a lambda is an
expression (probably used in an enclosing statment), it doesn’t get to
have generic code blocks. With some rework, blocks delimited by
indentation don’t have to be so limited.


#20

Rick DeNatale wrote:

On 5/22/07, M. Edward (Ed) Borasky removed_email_address@domain.invalid wrote:

  1. Both curly braces and begin / end pairs to define scope, with one
    variant having a higher binding priority than the other. The fact that I
    don’t even remember which one it is that has the higher binding priority
    is an added factor in my dislike.

I think there’s some misunderstanding here.

Curly braces are used to denote a proc, begin/end delimits a sequence
of expressions which are executed in sequence and whose value is the
last expression executed.

Ed probably meant do…end, not begin…end.

{} and do/end aren’t operators, but in almost all cases delimit procs
and so the question of their relative priority is moot as far as I can
tell since you can’t have two procs next to each other in ruby source.

This is the precedence issue:

def foo(*)
puts “FOO” if block_given?
end

def bar(*)
puts “BAR” if block_given?
end

foo bar do end
foo bar { }

END

Output:

FOO
BAR