Feature Request: Truly Indented Here-Docs

  • Thread starter James Edward Gray II
  • Start date
J

James Edward Gray II

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
 
D

David A. Black

Hi --

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

This has come up before; I don't remember what the state of discussion
was as of the end of the last iteration, but you'll find stuff in the
ruby-talk (or ruby-core, but I think ruby-talk) archives from the past
year or less. (I'm being lazy and not looking it up myself, but it's
there :)


David
 
T

trans. (T. Onoma)

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

Siegfried Heintze

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
 
G

Gavin Kistner

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

Marcel Molina Jr.

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
 
G

Gavin Sinclair

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
 
A

Andrew Johnson

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
 
D

Dick Davies

* Siegfried Heintze said:
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 ^_^
 
D

David G. Andersen

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/multiconsole.rb

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

-dave
 
B

Brian Candler

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-talk/111331
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/111330

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

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.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top