Endless Ruby 0.0.2


#1

endless.rb is a pre-processor for ruby which allows you to use
python-ish
indentation to delimit scopes, instead of having to type ‘end’ every
time.

http://gist.github.com/117694

Basically, this 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.
Since endless.rb uses RubyLexer, it should be able to handle almost
all ruby syntax.

Examples:

begin
a
b

begin
a
rescue
b
else
d
ensure
c

class A
class B
class C
module D
foo

def a b
c
d

for i in 1…10 do
p i
pp i

To be endless in your own code, you must first require ‘endless.rb’,
then load files which are written endlessly using Endless.load, rather
than the usual plain vanilla load (or require). (Endless.require isn’t
written yet, sorry.)

require ‘endless’
Endless.load ‘my-endless-code.rb’

Changes in this release:
Re-worked the way the def keyword is processed, to fix several bugs.
The new way is even a little bit less hacky.
Insert a space before implicit ends

Install:
endless.rb is available as a gist (jest?) on github only:
http://gist.github.com/117694


#2

Caleb C. wrote:

endless.rb is a pre-processor for ruby which allows you to use python-ish
indentation to delimit scopes, instead of having to type ‘end’ every time.

Oh dear god no!

Seriously though…neat :slight_smile:

  • Charlie

#3

Charles Oliver N. wrote:

Caleb C. wrote:

endless.rb is a pre-processor for ruby which allows you to use
python-ish
indentation to delimit scopes, instead of having to type ‘end’ every
time.

Oh dear god no!

Seriously though…neat :slight_smile:

Both my emotions neatly summed up!

Cheers,
Mohit.
5/29/2009 | 12:28 PM.


#4

Caleb C. wrote:

To be endless in your own code, you must first require ‘endless.rb’,
then load files which are written endlessly using Endless.load, rather
than the usual plain vanilla load (or require). (Endless.require isn’t
written yet, sorry.)

Ouch. But this is a good candidate for using Polyglot. Just name
your files .rbe, and when you require ‘endless’, it registers that
extension with Polyglot to be used with the endless loader. Then
you can just “require ‘fred’”, and it will endless-load “fred.rbe”.


#5

On May 29, 2009, at 12:46 AM, Clifford H. wrote:

extension with Polyglot to be used with the endless loader. Then
you can just “require ‘fred’”, and it will endless-load “fred.rbe”.

How would this work? Would endless.rb just load the polyglot gem
and automatically set itself up? So all you’d need to do is require
‘endless’ and
then make some rbe files?


#6

for i in 1…10 do
p i
pp i

wonder if do-less ruby would possible, too
for i in 1…10
p i
pp i

or braceless or something

3.times |n|
puts n

:slight_smile:
-=r


#7

On 5/28/09, Clifford H. removed_email_address@domain.invalid wrote:

Caleb C. wrote:

To be endless in your own code, you must first require ‘endless.rb’,
then load files which are written endlessly using Endless.load, rather
than the usual plain vanilla load (or require). (Endless.require isn’t
written yet, sorry.)

Ouch. But this is a good candidate for using Polyglot. Just name
your files .rbe, and when you require ‘endless’, it registers that
extension with Polyglot to be used with the endless loader. Then
you can just “require ‘fred’”, and it will endless-load “fred.rbe”.

This is very interesting, I could use this in RubyMacros as well. But
then that brings up another issue; what if I want to use both at once?
Aside from the trouble of actually getting the two to work together,
how does a user specify that some particular combination of
preprocessors is to be used? Extending your example, I could use .rbm
for files with macros in them, but what about files without ends and
with macros? .rbem? While Polyglot’s extension registration system is
nice, I’m wanting something more sophisticated as well.

Michael Bruschkewitz wrote: (in another thread)

At breakfast I had the idea it would be possible to implement/apply it to current file it by
simply using
“require ‘tool4endH8ers.rb’” or
“require ‘languageConverter_pyi.rb’” or
“require ‘languageConverter_BASIC.rb’” or
“require ‘languageConverter_f77.rb’” or…
“require ‘applySomeOtherWeirdOptions.rb’” or…
at the beginning of each file or at the beginning of main file.
I’m sure some Kernel.magic would make this possible.

I’m not entirely sure, but it seems like he’s saying that if you
should be able to require “languageConverter_f77.rb”, and then write
the rest of the file in fortran. A bit far-fetched, but I like the
idea of being able to declare the format up at the top of the file,
perhaps with a magic comment.

Why not think about providing a mechanism which provides this possibility?

Hmm, what about it, Clifford? Seems like an appropriate thing to add
to Polyglot…

PS: the examples on this page got damaged somehow:
http://polyglot.rubyforge.org/


#8

Caleb C. wrote:

endless.rb […] makes the end keyword optional.

I love this idea and already implemented it for eRuby:

http://snk.tuxfamily.org/lib/ember/#Infer-block-endings

Where ‘<% end %>’ is more laborious to type than ‘end’. :slight_smile:


#9

Juan Z. wrote:

Ouch. But this is a good candidate for using Polyglot. Just name
your files .rbe, and when you require ‘endless’, it registers that
extension with Polyglot to be used with the endless loader. Then
you can just “require ‘fred’”, and it will endless-load “fred.rbe”.
How would this work? Would endless.rb just load the polyglot gem
and automatically set itself up? So all you’d need to do is require
‘endless’ and then make some rbe files?

Exactly. My ActiveFacts gem implements a language called CQL.
When you require ‘activefacts/cql’, it does this:

require ‘polyglot’
module ActiveFacts
class CQLLoader
def self.load(file)

end
end
Polyglot.register(‘cql’, CQLLoader)
end

Now you can require ‘fred’, and CQLLoader gets to load “fred.cql”
(assuming that “fred.rb” isn’t found first). The CQL is translated
into Ruby module and class definitions which are then eval’ed.

Same deal with Treetop. When you require ‘treetop’, it requires
Polyglot, and does this:

Polyglot.register([“treetop”, “tt”], Treetop)

where the Treetop class has a self.load method.

Clifford H…


#10

Caleb C. wrote:

Ouch. But this is a good candidate for using Polyglot. Just name
your files .rbe, and when you require ‘endless’, it registers that
extension with Polyglot to be used with the endless loader. Then
you can just “require ‘fred’”, and it will endless-load “fred.rbe”.

This is very interesting, I could use this in RubyMacros as well. But
then that brings up another issue; what if I want to use both at once?

I think you’d need to create a custom loader that knows how to load the
file having combined syntax.

When Nathan Sobo created Treetop, one of his hopes was that Ruby
could eventually incorporate PEG parsing technology and add his “rule”
keyword. Because PEG parsers are composable, this would allow you to
define new parse rules within a Ruby program, which would integrate
fully into the existing Ruby grammar, or be used to introduce new
sub-languages that mesh in nicely… My take on that was then to
extend Kernel.require so that each file extension used a different
top-level parse rule from within the combined grammar, and you have
a full meta-language framework… That’s kinda what Polyglot is about.

It’s kinda what you’re talking about below, but done “properly”.

Aside from the trouble of actually getting the two to work together,
how does a user specify that some particular combination of
preprocessors is to be used? Extending your example, I could use .rbm
for files with macros in them, but what about files without ends and
with macros? .rbem? While Polyglot’s extension registration system is
nice, I’m wanting something more sophisticated as well.

Rails went with chained processors, like file.html.erb, etc. Polyglot’s
loader isn’t currently defined to read the input file and yield content
for a subsequent loader, but chaining like that is a possible extension.

I’m not entirely sure, but it seems like he’s saying that if you
should be able to require “languageConverter_f77.rb”, and then write
the rest of the file in fortran. A bit far-fetched, but I like the
idea of being able to declare the format up at the top of the file,
perhaps with a magic comment.

Why not think about providing a mechanism which provides this possibility?

Hmm, what about it, Clifford? Seems like an appropriate thing to add
to Polyglot…

It’s certainly possible. How would one loader pass output to the next?
I wouldn’t want to create the intermediate content as files.

PS: the examples on this page got damaged somehow:
http://polyglot.rubyforge.org/

Thanks, I’ll look at it.

Clifford H…


#11

On 5/30/09, Clifford H. removed_email_address@domain.invalid wrote:

This is very interesting, I could use this in RubyMacros as well. But
then that brings up another issue; what if I want to use both at once?

I think you’d need to create a custom loader that knows how to load the
file having combined syntax.

Typically, yes. And that’s the biggest challenge. (If you’re lucky,
you might be able to make earlier stages of the pipeline tolerant
enough to just pass through new syntax which they don’t understand.)

When Nathan Sobo created Treetop, one of his hopes was that Ruby
could eventually incorporate PEG parsing technology and add his “rule”
keyword. Because PEG parsers are composable, this would allow you to
define new parse rules within a Ruby program, which would integrate
fully into the existing Ruby grammar, or be used to introduce new
sub-languages that mesh in nicely… My take on that was then to

That’s cool, even if I have no idea how this composable grammar would
work. I have similar goals with RubyMacros, which right now is still
very far from that level of flexibility. I actually
hope macros will be a somewhat more approachable interface to the same
idea.

extend Kernel.require so that each file extension used a different
top-level parse rule from within the combined grammar, and you have
a full meta-language framework… That’s kinda what Polyglot is about.

It’s kinda what you’re talking about below, but done “properly”.

I can see the attraction of not needing to parse and unparse things
all the time.

It’s certainly possible. How would one loader pass output to the next?
I wouldn’t want to create the intermediate content as files.

Maybe a pipe? I suggest it reluctantly since I don’t think my own
tools can use a pipe. Ruby is complicated, and it’s nice to be able to
seek back and forth in the input stream. I don’t see what’s wrong with
a temp file; it’s better than a string. Or you can define some kind of
api for connecting preprocessors, but I can’t see the advantage of it
over one of those three possibilities.


#12

On 5/29/09, Roger P. removed_email_address@domain.invalid wrote:

wonder if do-less ruby would possible, too
for i in 1…10
p i
pp i

You can leave off the do in for, until, and while loops already. I
usually do.

or braceless or something

3.times |n|
puts n

(shudder). You realize that that one already parses like:

3.times.|(n).|(puts n)


#13

Sounds really cool so far, have to test it heavily before I can make an
“informed” opinion (other than right now that I think this rocks. Having
as many options available as possible is always good IMO before
“deciding” on something, in general.)


#14

Got a problem, perhaps one of you knows how to resolve (note, I did not
use gems but rather installed rubylex 0.7.5 from the tarball):

rubylexer/rulexer.rb:36:in `require’: no such file to load –
sequence/indexed (LoadError)


#15

Caleb C. wrote:

endless.rb is a pre-processor for ruby which allows you to use
python-ish
indentation to delimit scopes, instead of having to type ‘end’ every
time.

http://gist.github.com/117694

Basically, this makes the end keyword optional.

One thought might be to name is “end implied” or “end optional” since
you can still use end :slight_smile:

Speaking of which, did J Haas ever come up with a way to do

b = case y
when 3
4
end if true

without using an end keyword?

-=r


#16

“Caleb C.” removed_email_address@domain.invalid schrieb im Newsbeitrag > Michael
Bruschkewitz wrote: (in another thread)

I’m not entirely sure, but it seems like he’s saying that if you
should be able to require “languageConverter_f77.rb”, and then write
the rest of the file in fortran.

That’s exactly may idea, until next required “converter”… or some end
marker.
It wold be similar to eval_f77 << END_OF_F77CODE …
Core question remaining: Who writes those converters?

Also:
F77 (or some other compiled langauge) converter could, for example,
automatically wrap and compile the source and create a dynamic library
which
is used through standard require functionality.

This could easily be done by some aliasing for require:
def new_require s
if s.ends_with? ‘.f77’
temporary_lib_name = wrap_compile_and_link s
old_reqiuire s
end
end

Get the idea?
All what’s needed is to write wrappers for other languages and to speed
up
the process, maybe by checksumming the sources and putting checksum into
lib.
And probably, some problems to be dealt with run-time-lib-initialization
of
the langauges.

Maybe Polyglot does similar things? (Had no time to check - need to
rescue
my child from school now.)


#17

Ok this is my last remark for some time, else I might appear as spamming
for which I apologize.

I have found sequence, it is on rubyforge too.

Here is the link for others to find it, in case they mightneed it:
http://rubyforge.org/frs/?group_id=2317&release_id=25335


#18

“Eleanor McHugh” removed_email_address@domain.invalid schrieb im Newsbeitrag
news:removed_email_address@domain.invalid…

On 4 Jun 2009, at 15:10, Michael Bruschkewitz wrote:

That’s exactly may idea, until next required “converter”… or some
end marker.
It wold be similar to eval_f77 << END_OF_F77CODE …
Core question remaining: Who writes those converters?

I can’t help but wonder why bother when you could just write F77 code,
compile it and then use either ruby/dl or ruby-ffi to call it directly
from ruby.

I just want to remove the need for dealing with all those
interface-issues.
If I understood ruby-ffi description, there is a need to know which
types/byte sizes are used in the interface. Further sequence and
alignment.
Also there is a need for knowing how F77 (weird example, I know) handles
parameters, global data, function names etc.

Using converters:
If there is one developer (ex.: mathematician) which knows F77 and
another
developer which knows Ruby are working in one team - none of both would
need
to know how dynamic libraries are created or what a dynamic library in
detail is or if they exist on that particular used platform at all. The
converter could hide all this knowledge, thus allowing the developers to
concentrate on the solution of project-related problems.

This interface knowledge is not related to particular projects, but to
languages. There is only the need for some common interface format. How
interfaces are exported/imported could be completely transparent to the
developer. Such an converter needs to be created only once per language.

Michael B.


#19

On 4 Jun 2009, at 15:10, Michael Bruschkewitz wrote:

at the beginning of each file or at the beginning of main file.
I’m sure some Kernel.magic would make this possible.

I’m not entirely sure, but it seems like he’s saying that if you
should be able to require “languageConverter_f77.rb”, and then write
the rest of the file in fortran.

That’s exactly may idea, until next required “converter”… or some
end marker.
It wold be similar to eval_f77 << END_OF_F77CODE …
Core question remaining: Who writes those converters?

I can’t help but wonder why bother when you could just write F77 code,
compile it and then use either ruby/dl or ruby-ffi to call it directly
from ruby.

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason


#20

On 6 Jun 2009, at 22:05, Michael Bruschkewitz wrote:

another developer which knows Ruby are working in one team - none of
only once per language.
This is a naive assumption as it ignores the fact that many languages
either have loose standards or no standard at all, therefore the
amount of work required to implement such converters could be many
orders of magnitude greater than that required to learn an FFI
extension such as ruby/dl or ruby-ffi.

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason