Ruby Continue String on Next Line

line continuation


Author Message

 line continuation

can a ruby statement break into multiple lines?
if not, is there a line continuation symbol in ruby?

thx,
david

_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.*-*-*.com/ .

Wed, 16 Jul 2003 16:43:34 GMT

 line continuation

Quote:

> can a ruby statement break into multiple lines?
> if not, is there a line continuation symbol in ruby?

Yes, if you have the Ruby-book see page 201.
A statement break into mutliple lines if it is not complete,
i.e. "if the last token on a line is an operator or comma".
But you can also use \ as the last character on the line, to
continue on the next line.

a = 2 +
3
is equivalent to a=2+3

a = 2  \
+ 3

here you need the \ at the end of the line.

--
Michael Neumann

Wed, 16 Jul 2003 18:10:21 GMT

 line continuation

Quote:

>A statement break into mutliple lines if it is not complete,
>i.e. "if the last token on a line is an operator or comma".
>But you can also use \ as the last character on the line, to
>continue on the next line.

>a = 2 +
>    3
>is equivalent to a=2+3

>a = 2  \
>    + 3

>here you need the \ at the end of the line.

While it's nice that you can do this, can someone explain why it is
that the Ruby parser can't work out that a statement is not finished,
as, say, a C++ or Java parser can?

I assume it makes the parsing a little easier, but I do find it a pain
each time I get a syntax error because of this sort of thing and it
takes me a while to realise what the problem is.

Thu, 17 Jul 2003 08:02:47 GMT

 line continuation

Quote:

> While it's nice that you can do this, can someone explain why it is
> that the Ruby parser can't work out that a statement is not finished,
> as, say, a C++ or Java parser can?

Because C++ and Java statements are terminated with a ; .

-spc

Thu, 17 Jul 2003 08:04:17 GMT

 line continuation

Quote:

> While it's nice that you can do this, can someone explain why it is
> that the Ruby parser can't work out that a statement is not finished,
> as, say, a C++ or Java parser can?

Very simple - C++ and Java make you end every statement with a semicolon.
This makes parsing much *easier* for them - Ruby has to do a little more
work, but it can't read your mind...

Thu, 17 Jul 2003 08:17:06 GMT

 line continuation

Quote:

----- Original Message -----

Sent: Saturday, January 27, 2001 4:10 PM
Subject: [ruby-talk:9988] Re: line continuation

> >A statement break into mutliple lines if it is not complete,
> >i.e. "if the last token on a line is an operator or comma".
> >But you can also use \ as the last character on the line, to
> >continue on the next line.

> >a = 2 +
> >    3
> >is equivalent to a=2+3

> >a = 2  \
> >    + 3

> >here you need the \ at the end of the line.

> While it's nice that you can do this, can someone explain why it is
> that the Ruby parser can't work out that a statement is not finished,
> as, say, a C++ or Java parser can?

> I assume it makes the parsing a little easier, but I do find it a pain
> each time I get a syntax error because of this sort of thing and it
> takes me a while to realise what the problem is.

Well, for one thing, Ruby has no required statement terminator (semicolon).
And remember, a standalone expression is valid in Ruby.

Thus

    a = 2
+3

is actually two statements, isn't it?

Hal Fulton

Thu, 17 Jul 2003 08:16:32 GMT

 line continuation

Quote:

> >A statement break into mutliple lines if it is not complete,
> >i.e. "if the last token on a line is an operator or comma".
> >But you can also use \ as the last character on the line, to
> >continue on the next line.

> >a = 2 +
> >    3
> >is equivalent to a=2+3

> >a = 2  \
> >    + 3

> >here you need the \ at the end of the line.

> While it's nice that you can do this, can someone explain why it is
> that the Ruby parser can't work out that a statement is not finished,
> as, say, a C++ or Java parser can?

Because the code layout is, in many cases, the *only* information
about how the code should parse.  This is the price we pay for not
having to type semicolons.

Think of it this way: if we wrote sentences without periods (and
without starting with a capital letter :-), we'd probably need to put
a blank line between every two sentences in order to parse them
correctly.  (Blank line for us being the equivalent, in this analogy,
of newline for Ruby.)

David

--
David Alan Black

Web:  http://pirate.shu.edu/~blackdav

Thu, 17 Jul 2003 08:29:20 GMT

 line continuation

Quote:

> >A statement break into mutliple lines if it is not complete,
> >i.e. "if the last token on a line is an operator or comma".
> >But you can also use \ as the last character on the line, to
> >continue on the next line.

> >a = 2 +
> >    3
> >is equivalent to a=2+3

> >a = 2  \
> >    + 3

> >here you need the \ at the end of the line.

> While it's nice that you can do this, can someone explain why it is
> that the Ruby parser can't work out that a statement is not finished,
> as, say, a C++ or Java parser can?

I guess this was already answered in other mails.

Quote:

> I assume it makes the parsing a little easier, but I do find it a pain
> each time I get a syntax error because of this sort of thing and it
> takes me a while to realise what the problem is.

I wrote to relief your pre-pains a bit.

I agree it's a pain in the ass to get syntax error because of missed
'\'. But it's quite rare event. First, this particular case doesn't
give syntax error (and actually creates even more pain as a side
effect). Then the second reason is that this is a case you just have
to remember. The memory aid is there: the same works in same way in
many other languages too. But you have to remember the "rule" by
yourself. Most people do remember, and thus the overall harmful effect
is sufficiently small.

Anyway, this bug doesn't bite too often by accident. If you adopt
"right" style to write code (include operator or dot as a hint of
continuation to the same line) it's very rare event you need
'\'. During my sufficiently short Ruby career I can't remember using
this notation more than two times.

Usually when a statement grows over line there's something in your
code which uses it's last way of signalling it should be fixed.

   - Aleksi

Thu, 17 Jul 2003 08:35:57 GMT

 line continuation

Quote:

>> While it's nice that you can do this, can someone explain why it is
>> that the Ruby parser can't work out that a statement is not finished,
>> as, say, a C++ or Java parser can?

>Very simple - C++ and Java make you end every statement with a semicolon.
>This makes parsing much *easier* for them - Ruby has to do a little more
>work, but it can't read your mind...

I think the answer is more complex than that and has to do with the
allowed language constructs (as pointed out in a previous post).  As a
counter example, Eiffel does not require statements to end with a
semi-colon and also allows a statement to be spread out over several lines
(without a \).
--
Jim Cochrane

Thu, 17 Jul 2003 10:26:51 GMT

 line continuation

Quote:

> Anyway, this bug doesn't bite too often by accident. If you adopt
> "right" style to write code (include operator or dot as a hint of
> continuation to the same line) it's very rare event you need
> '\'. During my sufficiently short Ruby career I can't remember using
> this notation more than two times.

> Usually when a statement grows over line there's something in your
> code which uses it's last way of signalling it should be fixed.

I disagree with that, since it is in the style of functional programming to
have a large "chain" of methods acting upon a series of lists (or, in Ruby's
case, Arrays).  For example:

    def CDDB.from_sql(res)
unsubber = lambda {|s|
s.scan(/[^\\]("([^"\\]|\\.)*")/).
collect {|e| e[0][1..-2].gsub(/\\(.)/, '\1')}
}
CDDBStruct.new(unsubber.call(res[0]), res[1], unsubber.call(res[2]),
res[3], unsubber.call(res[4]),
res[5][1..-2].split(',').collect {|x| x.to_i})
end

You'll probably see even longer chains than that all the time, and in those
cases I think that when a statement is more than a line because of this,
it's specifically doing things right!

--
Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /

Thu, 17 Jul 2003 13:04:46 GMT

 line continuation

Quote:

> > Anyway, this bug doesn't bite too often by accident. If you adopt
> > "right" style to write code (include operator or dot as a hint of
> > continuation to the same line) it's very rare event you need
> > '\'. During my sufficiently short Ruby career I can't remember using
> > this notation more than two times.

> > Usually when a statement grows over line there's something in your
> > code which uses it's last way of signalling it should be fixed.

> I disagree with that, since it is in the style of functional programming to
> have a large "chain" of methods acting upon a series of lists (or, in Ruby's
> case, Arrays).  For example:

>     def CDDB.from_sql(res)
>         unsubber = lambda {|s|
>             s.scan(/[^\\]("([^"\\]|\\.)*")/).
>               collect {|e| e[0][1..-2].gsub(/\\(.)/, '\1')}
>         }
>         CDDBStruct.new(unsubber.call(res[0]), res[1], unsubber.call(res[2]),
>           res[3], unsubber.call(res[4]),
>           res[5][1..-2].split(',').collect {|x| x.to_i})
>     end

> You'll probably see even longer chains than that all the time, and in those
> cases I think that when a statement is more than a line because of this,
> it's specifically doing things right!

While I agree with you that there's a certain tendency to produce
chains of calls, I have to keep staying behind my opinion. My very
argument against this style of coding is the fact that it's painful to
read above code, and even more painful to change it.

I like call chaining, even to the point I really like to get away with
most method! anomalities (returning nil sometimes; actually I fixed
one of these from someone else's code which didn't work for me).

Simultaneously when you reorganize the above code there's an effect
that you give name to a thing you handle; be it a command chain,
a parameter or a helper variable.

     def CDDB.from_sql(res)
quoted_string_re = /[^\\]("([^"\\]|\\.)*")/
unsubber = lambda do |s|
s.scan(quoted_string_re).collect do |e|
e[0][1..-2].gsub(/\\(.)/, '\1')}
end
end
listed_numbers = res[5][1..-2].split(',').collect {|x| x.to_i}
CDDBStruct.new(unsubber.call(res[0]), res[1],
unsubber.call(res[2]), res[3],
unsubber.call(res[4]), listed_numbers)
end

I'm not claiming this example is in some way the ultimate, most
readable version, but I find my version easier to read and mess
around.

Still I'd like to exploit the possible rule of "unsub every second
parameter", name the mystical range of 1..-2, give better names to
variables in unsubber, maybe split the long line of listed_numbers
definition into two lines and call collect! on the latter.

Anyway, I guess you get my point. I think it's quite rare event that
you really have to have over 75 character (or some limit) lines. I
hear the exceeding line length as a cry requesting some code massage.

There are some simple cases where the change is easy to do, like
spreading inlined blocks to multiple lines ({..} notation to do..end),
and with parameter passing I feel no guilty having couple of lines
between opposing parentheses (as long as the content doesn't contain
too much of executed code).

Do we still disagree ?)

    - Aleksi

Thu, 17 Jul 2003 19:15:11 GMT

 line continuation

Hi --

Quote:

> Anyway, I guess you get my point. I think it's quite rare event that
> you really have to have over 75 character (or some limit) lines. I
> hear the exceeding line length as a cry requesting some code massage.
>=20
> There are some simple cases where the change is easy to do, like
> spreading inlined blocks to multiple lines ({..} notation to do..end),

I'm just curious -- do you make that distinction automatically (single
line use {}, multi line use do/end)?

David

--=20
David Alan Black

Web:  http://pirate.shu.edu/~blackdav

Thu, 17 Jul 2003 20:04:16 GMT

 line continuation

Quote:

> I'm just curious -- do you make that distinction automatically (single
> line use {}, multi line use do/end)?

Not speaking for Aleksi, but it's a convention that I like. It seems
to make the blocks fit in better with the other language constructs:

   for cd in collection
cd.each_track do |title|
# ...
end
end

to me looks cleaner than

   for cd in collection
cd.each_track { |title|
# ...
}
end

There's another style I;ve seen her which I'm still thinking
about. Some folks put the block parameters on their own line:

   a.doit {
| name, address |
# ...
}

It certainly looks nice, but I can't quite convince myself there's a
reason to do it ;-)

Dave

Thu, 17 Jul 2003 21:38:01 GMT

 line continuation

Quote:

> > I'm just curious -- do you make that distinction automatically (single
> > line use {}, multi line use do/end)?

> Not speaking for Aleksi, but it's a convention that I like. It seems
> to make the blocks fit in better with the other language constructs:

>    for cd in collection
>       cd.each_track do |title|
>          # ...
>       end
>    end

> to me looks cleaner than

>    for cd in collection
>       cd.each_track { |title|
>          # ...
>       }
>    end

I agree -- though I'm not to be trusted, as I also tend to like the
highly unpopular placing of do/end on one line....  In fact, I've gone
over almost exclusively to do/end, especially now that one can chain
them.

Quote:

> There's another style I;ve seen her which I'm still thinking
> about. Some folks put the block parameters on their own line:

>    a.doit {
>      | name, address |
>      # ...
>    }

> It certainly looks nice, but I can't quite convince myself there's a
> reason to do it ;-)

I originally liked doing that, especially with do/end:

  things.each do
|t|
puts t
end

An argument could be made that breaking the line between the "do"
directive and the start of what it is you're "do"ing makes sense.

I've actually trained myself to put the |t| right by the "do" because
I didn't see many people using the above style.  But it does seem to
be appearing more.

David

--
David Alan Black

Web:  http://pirate.shu.edu/~blackdav

Thu, 17 Jul 2003 21:50:21 GMT

 line continuation

Quote:


> > > Anyway, this bug doesn't bite too often by accident. If you adopt
> > > "right" style to write code (include operator or dot as a hint of
> > > continuation to the same line) it's very rare event you need
> > > '\'. During my sufficiently short Ruby career I can't remember using
> > > this notation more than two times.

> > > Usually when a statement grows over line there's something in your
> > > code which uses it's last way of signalling it should be fixed.

> > I disagree with that, since it is in the style of functional programming to
> > have a large "chain" of methods acting upon a series of lists (or, in Ruby's
> > case, Arrays).  For example:

> >     def CDDB.from_sql(res)
> >         unsubber = lambda {|s|
> >             s.scan(/[^\\]("([^"\\]|\\.)*")/).
> >               collect {|e| e[0][1..-2].gsub(/\\(.)/, '\1')}
> >         }
> >         CDDBStruct.new(unsubber.call(res[0]), res[1], unsubber.call(res[2]),
> >           res[3], unsubber.call(res[4]),
> >           res[5][1..-2].split(',').collect {|x| x.to_i})
> >     end

> > You'll probably see even longer chains than that all the time, and in those
> > cases I think that when a statement is more than a line because of this,
> > it's specifically doing things right!

> While I agree with you that there's a certain tendency to produce
> chains of calls, I have to keep staying behind my opinion. My very
> argument against this style of coding is the fact that it's painful to
> read above code, and even more painful to change it.

You think so?  My eyes, when following it, are drawn to the periods and the
matching parentheses/braces/brackets.  In other words, my ... style? ...
will often include more punctuation whereas yours will include whitespace
because that's what really helps you visually pick out control flow.

Quote:

> I like call chaining, even to the point I really like to get away with
> most method! anomalities (returning nil sometimes; actually I fixed
> one of these from someone else's code which didn't work for me).

Example (evil one, maybe :) from the same file:

        subber = lambda {|s|
s.gsub!(/(\\*)\\n/) {$1.length[0] == 1 ? $1 + "\n" : $&}
s.gsub!(/(\\*)\\t/) {$1.length[0] == 1 ? $1 + "\t" : $&}
s.gsub!(/\\\\/, '\\')
s.gsub!(/'/, "''")
s.gsub!(/[{}]/, '\\\\\0')
s
}

It's not actually chained because I decided to use the bang-methods.
I think that because every line lines up the same, it's a very clear idiom
for performing a series of operations.  I'm not sure which I prefer.

Also, I notice that I tend to give ephemeral arguments one-letter names.
How shell-scripty!

Quote:

> Simultaneously when you reorganize the above code there's an effect
> that you give name to a thing you handle; be it a command chain,
> a parameter or a helper variable.

>      def CDDB.from_sql(res)
>          quoted_string_re = /[^\\]("([^"\\]|\\.)*")/
>          unsubber = lambda do |s|
>              s.scan(quoted_string_re).collect do |e|
>                  e[0][1..-2].gsub(/\\(.)/, '\1')}
>              end
>          end
>          listed_numbers = res[5][1..-2].split(',').collect {|x| x.to_i}
>          CDDBStruct.new(unsubber.call(res[0]), res[1],
>                         unsubber.call(res[2]), res[3],
>                         unsubber.call(res[4]), listed_numbers)
>      end

> I'm not claiming this example is in some way the ultimate, most
> readable version, but I find my version easier to read and mess
> around.

I'm one of those people that believe that if you're only using something
once, it's usually wrong to give it a name unless otherwise it would truly
make things very hard to follow.  In this specific case, I usually /try/ to
let my regexps speak for themselves.  If they're so hard to follow that I
can't tell what they're for, they're probably not very good at all :)  For
instance, key to this one is it's "something in quotes not preceded by a
backslash consisting of a series of strings that are either not a quote, not
a backslash, or a backslash followed by anything".  This regexp, to me, is
an important part of the code, so it should be read and understood like any
of the rest.

I agree that using listed_numbers probably does make things that much easier
to follow for a lot of people.  I was brought up on the BSD KNF style in C,
which dictates (8-space) tabs for indentation but  four spaces for statement
continuation.  I carry this to Ruby by using (4-space) tabs and 2-space
statement continuation indentation, like in the CDDBStruct.new() call.  This
is just the way I've been "raised": make the whitespace always mean
something when it's there and always be consistent.  Something I forgot
about in this case is at least attempting to make the lines more uniform, so
I'd personally want to use something more like:

        CDDBStruct.new(unsubber.call(res[0]),
res[1], unsubber.call(res[2]),
res[3], unsubber.call(res[4]),
res[5][1..-2].split(',').collect {|x| x.to_i})

Uniformity makes it a bit more pleasing, but you're right that it can't be
as uniform as it could when the arguments are all converted to a form which
make lining up more possible.  I could go either way.

Quote:

> Still I'd like to exploit the possible rule of "unsub every second
> parameter", name the mystical range of 1..-2, give better names to
> variables in unsubber, maybe split the long line of listed_numbers
> definition into two lines and call collect! on the latter.

I don't think that's a very good rule, because it's really just...
coincidental:

    CDDBStruct = Struct.new('CDDB',
:discid, :dtitle, :ttitle, :extd, :extt, :playorder)

Stored in SQL, it's:

... freedb (discid text[], dtitle text, ttitle text[],
extd text, extt text[], playorder int[]);

The range 1..-2 will probably be seen an awful lot as the most common idiom
for taking the "inside" of a string.  I can't think of any way to express it
better :)  I still feel not giving things names until the end of a chain is
a good thing.  For the listed_numbers, it's "take the sixth result, without
the first and last characters, tokenize it by commas, and convert the array
of strings to an array of integers".

Quote:

> Anyway, I guess you get my point. I think it's quite rare event that
> you really have to have over 75 character (or some limit) lines. I
> hear the exceeding line length as a cry requesting some code massage.

> There are some simple cases where the change is easy to do, like
> spreading inlined blocks to multiple lines ({..} notation to do..end),
> and with parameter passing I feel no guilty having couple of lines
> between opposing parentheses (as long as the content doesn't contain
> too much of executed code).

> Do we still disagree ?)

It's a matter of style :)  I feel you raise a lot of good points, but I find
my ethos on it to be different from yours.  So, I agree to disagree on parts
of it, but I agree with you when you suggest that making things more
"documentary" is useful.  Perhaps I should use comments some time...

P.S.: I just noticed that using Ruby for this kind of stuff rather than C,
saying nothing about the amount of code needed, I never need any comments in
the Ruby code to go back and understand any of it, but for C I always need
to comment all manner of uncomplicated code.

--
Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /

Thu, 17 Jul 2003 23:13:14 GMT
 [ 18 post ] Go to page: [1] [2]

Powered by phpBB® Forum Software

mcdowellwhoubson.blogspot.com

Source: http://computer-programming-forum.com/39-ruby/56fcc8e820612523.htm

0 Response to "Ruby Continue String on Next Line"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel