[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Feature Request: Truly Indented Here-Docs

James Gray

10/3/2004 3:56:00 AM

Ruby's here-doc syntax baffles me. I don't get the indent the end tag
feature.

string = <<-END_OF_STRING
Line one...
line two...
line three.
END_OF_STRING

That leaves all the tabs at the beginning of those lines, which then
begs the question, why did I bother to indent the end tag?

It would make a lot more sense to me if lines of a here-doc were
stripped of leading whitespace equal to the indention of the end tag.
Is there any reason this wasn't done, or isn't practical?

If not, please consider this an official request, by at least one
coder...

James Edward Gray II



10 Answers

dblack

10/3/2004 4:01:00 AM

0

T. Onoma

10/3/2004 4:11:00 AM

0

On Saturday 02 October 2004 11:55 pm, James Edward Gray II wrote:
> Ruby's here-doc syntax baffles me. I don't get the indent the end tag
> feature.
>
> string = <<-END_OF_STRING
> Line one...
> line two...
> line three.
> END_OF_STRING
>
> That leaves all the tabs at the beginning of those lines, which then
> begs the question, why did I bother to indent the end tag?
>
> It would make a lot more sense to me if lines of a here-doc were
> stripped of leading whitespace equal to the indention of the end tag.
> Is there any reason this wasn't done, or isn't practical?
>
> If not, please consider this an official request, by at least one
> coder...

I concur. That would be nice. Likewise I have asked about a margin controlled
literal (%l, %L). In the mean time I've used this on occasion:

class String
# provides a margin controlled string
#
# x = %Q{
# | This
# | is
# | margin controlled!
# }.margin
#
def margin(d='|')
gsub(/^\s*[#{d}]/, '')
end
end

Could work for here-docs too I suppose.

irb(main):001:0> require 'succ/string/tabs'
=> true
irb(main):002:0> t = <<-HERE.margin
irb(main):003:0" | test
irb(main):004:0" | this
irb(main):005:0" | out
irb(main):006:0" HERE
=> " test\n this\n out\n"

Yep.

T.


Siegfried Heintze

10/3/2004 4:25:00 AM

0

I need to write a program similar to a telnet server. A telnet server
asynchronously reads data from a socket and writes it to a
sub-process, and asynchronously reads data from the subprocess and
writes to a socket. My program needs to replace the subprocess with a
serial port.

The telnet server cannot anticipate when data will arrive from the
socket. Neither can it anticipate when data will arrive from the
subprocess.

How can I write a similar OS vendor neutral program using ruby,
except, instead reading and writing to a process, I read and write to
serial port? Can I do this with a single thread? How do I read and
write to a serial port? Can anyone point me to some sample code for
serial port I/O?

Thanks,
Siegfried




Gavin Kistner

10/3/2004 4:34:00 AM

0

On Oct 2, 2004, at 9:55 PM, James Edward Gray II wrote:
> It would make a lot more sense to me if lines of a here-doc were
> stripped of leading whitespace equal to the indention of the end tag.
> Is there any reason this wasn't done, or isn't practical?

Amen!

(As in +1, as in "I don't know of any reason, but I'd certainly like
it.")

Especially when you're inside a method, inside a smtp block, inside a
message block, writing out the body of an email which is the answer to
the current Ruby Quiz. :)


--
(-, /\ \/ / /\/



Marcel Molina Jr.

10/3/2004 6:15:00 AM

0

On Sun, Oct 03, 2004 at 12:55:51PM +0900, James Edward Gray II wrote:
> Ruby's here-doc syntax baffles me. I don't get the indent the end tag
> feature.
>
> string = <<-END_OF_STRING
> Line one...
> line two...
> line three.
> END_OF_STRING
>
> That leaves all the tabs at the beginning of those lines, which then
> begs the question, why did I bother to indent the end tag?
>
> It would make a lot more sense to me if lines of a here-doc were
> stripped of leading whitespace equal to the indention of the end tag.
> Is there any reason this wasn't done, or isn't practical?
>
> If not, please consider this an official request, by at least one
> coder...

if you want to have your here-doc indented to line up with your code
but don't want the here-doc's content to be indented (not what you are
really asking, i know), there is a pretty ugly way of doing this.

example:

class Blah
def indented_method_def_with_here_doc
string = <<-END_OF_STRING
This text won't have leading white space
even though the here-doc
is indented.
But is the gsubing stuff uglier than breaking
your indentation?
END_OF_STRING
string.gsub(Regexp.new('^' + string[/^\s+/]), '')
end
end

marcel
--
Marcel Molina Jr. <marcel@vernix.org>


Gavin Sinclair

10/3/2004 8:11:00 AM

0

On Sunday, October 3, 2004, 1:55:51 PM, James wrote:

> Ruby's here-doc syntax baffles me. I don't get the indent the end tag
> feature.

> string = <<-END_OF_STRING
> Line one...
> line two...
> line three.
> END_OF_STRING

> That leaves all the tabs at the beginning of those lines, which then
> begs the question, why did I bother to indent the end tag?

> It would make a lot more sense to me if lines of a here-doc were
> stripped of leading whitespace equal to the indention of the end tag.
> Is there any reason this wasn't done, or isn't practical?

> If not, please consider this an official request, by at least one
> coder...

I sympathise. What I do:

require 'extensions/string'

string = %{
| Line one...
| line two...
| line three.
}.trim('|')

Gavin



Andrew Johnson

10/3/2004 8:48:00 AM

0

On Sun, 3 Oct 2004 12:55:51 +0900, James Edward Gray II
<james@grayproductions.net> wrote:
[snip]

> It would make a lot more sense to me if lines of a here-doc were
> stripped of leading whitespace equal to the indention of the end tag.
> Is there any reason this wasn't done, or isn't practical?

I usually give my here-docs a block-like structure:

str = <<-DOC
line 1
line 2
DOC

so stripping leading spaces equal to indentation of the terminator-tag
wouldn't be my preference. I've found the following useful for stripping
common leading space:

class String
def dedent
a = $1 if match(/\A(\s*)(.*\n)(?:\1.*\n|\n)*\z/)
gsub(/^#{a}/, '')
end
end

# then later:

puts <<-DOC.dedent
* item 1
* item 1.2
* item 2
* item 2.1
DOC

andrew

Dick Davies

10/3/2004 10:51:00 AM

0

* Siegfried Heintze <siegfried@heintze.com> [1024 05:24]:
> I need to write a program similar to a telnet server. A telnet server
> asynchronously reads data from a socket and writes it to a
> sub-process, and asynchronously reads data from the subprocess and
> writes to a socket. My program needs to replace the subprocess with a
> serial port.

do you mean like tits? It's in C and written for NetBSD, but should be
easy enough to port to another *NIX. It should at least give you an idea
how the framework would work:

-------------------------------------------------------
rasputin@lb:booty$ cat /usr/pkgsrc/*/tits/DESCR
The tits command is a server process which provides telnet(1) access
to one or more tty ports as specified in config-file (or
/etc/tits.conf if no configuration file is specified on the command
line).

Any number of telnet(1) clients may connect to a single tits port.
Each client will see exactly the same output as well as being able to
send keystrokes simultaneously.
-------------------------------------------------------


Hang on, I just realised you are *never* going to find that via Google,
although it may be fun looking ^_^


-------------------------------------------------------
rasputin@lb:booty$ grep MASTER_SITES /usr/pkgsrc/*/tits/Makefile
MASTER_SITES= http://www.mctavish.c...
rasputin@lb:booty$
-------------------------------------------------------


> The telnet server cannot anticipate when data will arrive from the
> socket. Neither can it anticipate when data will arrive from the
> subprocess.
>
> How can I write a similar OS vendor neutral program using ruby,
> except, instead reading and writing to a process, I read and write to
> serial port? Can I do this with a single thread? How do I read and
> write to a serial port? Can anyone point me to some sample code for
> serial port I/O?

--
Everybody's a jerk. You, me, this jerk. - Bender
Rasputin :: Jack of All Trades - Master of Nuns


David G. Andersen

10/3/2004 11:10:00 PM

0

On Sun, Oct 03, 2004 at 07:50:50PM +0900, Dick Davies scribed:
> * Siegfried Heintze <siegfried@heintze.com> [1024 05:24]:
> > I need to write a program similar to a telnet server. A telnet server
> > asynchronously reads data from a socket and writes it to a
> > sub-process, and asynchronously reads data from the subprocess and
> > writes to a socket. My program needs to replace the subprocess with a
> > serial port.
>
> do you mean like tits? It's in C and written for NetBSD, but should be
> easy enough to port to another *NIX. It should at least give you an idea
> how the framework would work:

tits is probably what you want (what an unfortunate name for
a program). If you're really set on rewriting it in ruby, you
might find that my serial port management program helps get
you started, though beware -- it cuts a lot of corners because
it's connecting to a telnet server on the other end that handles
all of the telnet option negotiation and ugliness.

# multiconsole.rb - permit multiple concurrent 'telnet' processes
# to access a serial console server. All telnets see the same
# session (as a design choice), so don't use it for ordinary
# access. Convenient for having a console in your office
# and down in the machine room, though...

http://eep.lcs.mit.edu/multi...

It's a cheap hack, but it's mighty convenient. :)

-dave

--
work: dga@lcs.mit.edu me: dga@pobox.com
MIT Laboratory for Computer Science http://www....


Brian Candler

10/4/2004 8:24:00 AM

0

On Sun, Oct 03, 2004 at 01:24:47PM +0900, Siegfried Heintze wrote:
> How can I write a similar OS vendor neutral program using ruby,
> except, instead reading and writing to a process, I read and write to
> serial port? Can I do this with a single thread? How do I read and
> write to a serial port? Can anyone point me to some sample code for
> serial port I/O?

The module ruby-termios from RAA has examples of serial port I/O, and how to
set things like the bit rate and start/stop bits.

Beware: if you are using Linux, there is a serious bug with serial I/O and
Ruby, which means that I/O blocks when it shouldn't. I reported this on
ruby-talk and ruby-core, but nothing happened:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby...

It works fine under FreeBSD though, so conceivably it's a Linux kernel
problem.

As for threads etc: it depends on the application. If you're copying data to
a socket or to another process on stdin/stdout, then I'd use one thread to
read and another to write. Ruby threads are simulated threads, using
select() to determine when an FD is ready to read or write. That's as long
as you don't get bitten by the thread/serial port bug above, of course.

Regards,

Brian.