Forum: Ruby Perl to Ruby: regex captures to assignment.

Posted by Derrick B. (dbuckhal)
on 2012-12-19 22:45
Hello all,

I am converting a Perl program to Ruby in order to learn Ruby.  There is
an expression that takes a string, ("1 3/4" or "5", for example)
determines what kind of fraction was entered, and assigns variables (w,
n, d), appropriately.  If a whole number was entered, then it assigns
the variables differently, of course.

The expression first checks for the presence of a slash ("/") to
determine if it is a fraction or whole number.  Then, using the
conditional operator, assigns the variables, appropriately.

Here are the two expressions:

Perl:

    my ($w, $n, $d) = ( $frac_str =~ /\// )
            ? $frac_str =~ /(?:(\S+) )??(\S+)\/(\S+)/
            : ( 1, $frac_str, 0 );

Ruby:

    w, n, d = frac_str.match(/\//) \
        ? frac_str.match(/(?:(\S+) )*?(\S+)\/(\S+)/).captures \
        : 0, frac_str, 1
    puts "w: #{w}, n: #{n}, d: #{d}"  # check assignment


I used irb to test the regex and it works just fine:

exp = Regexp.new(/(?:(\S+) )*?(\S+)\/(\S+)/)
=> /(?:(\S+) )*?(\S+)\/(\S+)/

str = "1 3/4"
=> "1 3/4"

n, w, d = str.match(exp).captures
=> ["1", "3", "4"]

w
=> "3"

n
=> "1"

d
=> "4"

But, the above version outputs:

w: 134, n: 1 3/4, d: 1

It appears to recurse over the regex and duplicate the captures.  But,
since I am new to this language, I know I can use an 'if..else'
statement, but since I am coming from Perl, I figured that a similar
expression would "just work"!  :)

Thanks for your time and input,

Derrick
Posted by Matthew Kerwin (mattyk)
on 2012-12-20 00:35
(Received via mailing list)
As it is, the parser is interpreting the ternary operation as the first
item in the list, like:

    tmp = frac_str.match(/\//) \
      ? frac_str.match(/(?:(\S+) )*?(\S+)\/(\S+)/).captures \
      : 0
    w, n, d = tmp, frac_str, d

Subsequently puts(tmp) is calling Array#to_s which concatenates the
elements, so you see "134"

I got it to work by turning the third parameter of the ternary operation
into an explicit array:

    w, n, d = frac_str.match(/\//) \
      ? frac_str.match(/(?:(\S+) )*?(\S+)\/(\S+)/).captures \
      : [0, frac_str, 1]  # <= !!!
    puts "w: #{w}, n: #{n}, d: #{d}"  # check assignment

Outputs:  w: 1, n: 3, d: 4

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/
  ABN: 59-013-727-651

  "You'll never find a programming language that frees
  you from the burden of clarifying your ideas." - xkcd
Posted by Wei Feng (Guest)
on 2012-12-20 00:37
(Received via mailing list)
Try this:

w, n, d = frac_str =~ %r{/} \
? frac_str.match(%r{(?:(\S+) )*?(\S+)/(\S+)}).captures \
: [1, frac_str, 0]

I've use %r{} to quote regex, so no need to escape for /


On Thu, Dec 20, 2012 at 8:45 AM, Derrick B. <lists@ruby-forum.com> 
wrote:

> conditional operator, assigns the variables, appropriately.
>
>
> => "1"
> statement, but since I am coming from Perl, I figured that a similar
> expression would "just work"!  :)
>
> Thanks for your time and input,
>
> Derrick
>
> --
> Posted via http://www.ruby-forum.com/.
>
>


--
Regards,
Wei Feng

03 9005 3441 | M 0413 658 250 | windix@gmail.com | http://wei.feng.id.au
Posted by Matthew Kerwin (mattyk)
on 2012-12-20 00:37
(Received via mailing list)
On 20 December 2012 09:07, Matthew Kerwin <matthew@kerwin.net.au> wrote:

>
>
Sorry for replying to myself.  I just noticed that the Perl code also 
had
an explicit array,

     : ( 1, $frac_str, 0 )

Those brackety thingies are important, no matter which language you're
using.  ;)
Posted by 7stud -- (7stud)
on 2012-12-20 00:55
frac_str =  "1 3/4"

w, n, d =  frac_str.match(/\//) \
  ? frac_str.match(/(?:(\S+) )*?(\S+)\/(\S+)/).captures \
  : [0, frac_str, 1]

puts "w: #{w}, n: #{n}, d: #{d}"  # check assignment

--output:--
w: 1, n: 3, d: 4





frac_str =  "1 3/4"

md = frac_str.match %r{(\d+ )?(\d+)/(\d+)}
w, n, d = md ? md.captures : [frac_str.to_i, 0, 1]

puts "w: #{w}, n: #{n}, d: #{d}"  # check assignment

--output:--
w: 1 , n: 3, d: 4
Posted by 7stud -- (7stud)
on 2012-12-20 00:56
Matthew Kerwin wrote in post #1089658:
> On 20 December 2012 09:07, Matthew Kerwin <matthew@kerwin.net.au> wrote:
>
>>
>>
> Sorry for replying to myself.  I just noticed that the Perl code also
> had
> an explicit array,
>
>      : ( 1, $frac_str, 0 )
>

That isn't an array in perl--it's a list.  Ruby has a similar concept,
but as the op found out: the direct translation doesn't work in this
case.
Posted by Matthew Kerwin (mattyk)
on 2012-12-20 01:07
7stud -- wrote in post #1089660:
> Matthew Kerwin wrote in post #1089658:
>> On 20 December 2012 09:07, Matthew Kerwin <matthew@kerwin.net.au> wrote:
>>
>>>
>>>
>> Sorry for replying to myself.  I just noticed that the Perl code also
>> had
>> an explicit array,
>>
>>      : ( 1, $frac_str, 0 )
>>
>
> That isn't an array in perl--it's a list.  The direct translation from
> perl to ruby doesn't work in this case.

Semantically, and in the context, a Perl list is analogous with a ruby 
array. Since the languages are syntactically different (i.e. ruby 
doesn't allow delimited lists within a statement) and transliteration 
is, as you say, impossible, the most direct translation from a Perl list 
is to a ruby array.

If I, as a ruby programmer, when talking to a Perl programmer, say 
"array" when clearly the syntax includes round parentheses, I'm fairly 
confident they should be able to understand my intention.

If my slip was really that offensive, let me retract and rephrase as:

> Sorry for replying to myself.  I just noticed that the Perl code also
> had an explicit /list/,

Irrespective, it is still true that "those brackety thingies are 
important, no matter which language you're using."
Posted by Derrick B. (dbuckhal)
on 2012-12-20 01:38
First of all, thanks for the fast responses!

Secondly, I swear I tried bracketing the false side of the conditional
(pg 98, section 4.5.5.3 - "The Ruby Programming Language" book), but I
remember it assigning the array to the first variable - w.

In Perl, there are times when "those brackety thingies" are not
necessary, but as a programmer, I like readabiliy (yes, still talking
about Perl :) ) and will include them when it just makes sense.

Thanks all!
Posted by Hans Mackowiak (hanmac)
on 2012-12-20 07:14
how about this? use the magic of =~ to assign the local variables

w, n, d = 0, frac_str, 1 unless /(?:(?<w>\S+) )*?(?<n>\S+)\/(?<d>\S+)/ 
=~ frac_str
Posted by Robert Klemme (robert_k78)
on 2012-12-20 15:53
(Received via mailing list)
On Thu, Dec 20, 2012 at 1:38 AM, Derrick B. <lists@ruby-forum.com> 
wrote:
> First of all, thanks for the fast responses!
>
> Secondly, I swear I tried bracketing the false side of the conditional
> (pg 98, section 4.5.5.3 - "The Ruby Programming Language" book), but I
> remember it assigning the array to the first variable - w.

I would choose a completely different approach: I would have a single
expression for matching and decide which assignments to make based on
the value of one of the capturing groups in the conditional branch:

["1 3/4", "5"].each do |s|
  puts s

  if %r{\A(\d+)(?:\s+(\d+)/(\d+))?\z} =~ s
    w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [1, $1.to_i, 0]
    printf "%4d %4d %4d\n", w, n, d
  else
    $stderr.puts "No match #{s}"
  end
end

I also spiced the regexp a bit more to be more restrictive.

> In Perl, there are times when "those brackety thingies" are not
> necessary, but as a programmer, I like readabiliy (yes, still talking
> about Perl :) ) and will include them when it just makes sense.

If you like readability then why are you using Perl in the first place? 
:-)

Cheers

robert
Posted by Derrick B. (dbuckhal)
on 2012-12-20 19:23
Attachment: ratnum.rb (5,43 KB)
Attachment: ratnum.pl (6,91 KB)
Robert Klemme wrote in post #1089733:
>
> I would choose a completely different approach: I would have a single
> expression for matching and decide which assignments to make based on
> the value of one of the capturing groups in the conditional branch:
>
> ["1 3/4", "5"].each do |s|
>   puts s
>
>   if %r{\A(\d+)(?:\s+(\d+)/(\d+))?\z} =~ s
>     w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [1, $1.to_i, 0]
>     printf "%4d %4d %4d\n", w, n, d
>   else
>     $stderr.puts "No match #{s}"
>   end
> end
>
> I also spiced the regexp a bit more to be more restrictive.
>

I am prompting for input, so I would be parsing individual strings and
not a list of them.  Though I will remember that for future static
testing.  Also, I and using the "\S+" to handle negative rational
numbers: "-1 3/4".

>
> If you like readability then why are you using Perl in the first place?
> :-)
>

Because Perl is awesome!  That is why I chose Ruby as my next personal
choice of languages to learn.  I just completed a quarter of Programming
Language Concepts where I was introduced to Lisp, but was also required
to use some Python.  I know Python is a fascinatng language, but I am
not yet a big fan of it.  The final assignment was write a class to work
with fractions.  It started as a C++ class, then migrated to Perl (for
fun), and now Ruby (more fun).

I attached the two versions, Ruby and Perl.  The Perl version uses a
"class", also.  Feel free to suggest how to make the Ruby version more
Ruby-ish!  My goal is to take more advantage of the OO aspects of Ruby,
and not just have it look like Perl.

Thanks,

Derrick
Posted by 7stud -- (7stud)
on 2012-12-20 20:55
Derrick B. wrote in post #1089748:
>
> I am prompting for input, so I would be parsing individual strings and
> not a list of them.  Though I will remember that for future static
> testing.  Also, I and using the "\S+" to handle negative rational
> numbers: "-1 3/4".
>


test_data = [
  "3/4",
  "1 3/4",
  "-1 3/4",
  'hello'
]


test_data.each do |str|
  match_data = str.match(
   %r{
        (
          [-]?
          \d+
        )?
        \s*
        (\d+)
        /
        (\d+)
     }xms
  )

  w, n, d =  match_data ? match_data.captures: [str, 0, 1]
  puts "%s %s %s" % [w, n, d]

end

--output:--
 3 4
1 3 4
-1 3 4
hello 0 1
Posted by Derrick B. (dbuckhal)
on 2012-12-21 05:59
7stud -- wrote in post #1089755:
>    %r{
>         (
>           [-]?
>           \d+
>         )?
>         \s*
>         (\d+)
>         /
>         (\d+)
>      }xms
>   )
>

That works, but it needs another "[-]?" in the second group to handle
negative numerators, or whole numbers:

%r#(?:([-]?\d+) )??([-]?\d+)/(\d+)#xms

...but I should probably add the "\s*" and not expect a single space.  I
got the "??" from Perl, but it seems to not be a problem in Ruby.

Lastly, my code I posted did not convert terms to improper fractions,
correctly.  Here is the code that works:

Ruby:
    n = ( w == w.abs ) ?
        n + w * d :
        -1 * ( n - w * d ) if d != 0  # to negative improper fraction

Perl:
    $n = ( $w == abs($w) )
        ? $n + $w * $d                  # to positive improper fraction
        : -1 * ( $n - $w * $d ) if $d;  # to negative improper fraction

...which leads me to another question:

Why is it that when I try to add
a comment after a line continuation backslash, Ruby says:

./ratnum.rb:14: syntax error, unexpected $undefined
    n = ( w == w.abs ) ? \ #
                          ^
./ratnum.rb:15: syntax error, unexpected ':', expecting keyword_end

Ruby should respect my need for comments!  :)
Posted by botp (Guest)
on 2012-12-21 06:30
(Received via mailing list)
On Fri, Dec 21, 2012 at 12:59 PM, Derrick B. <lists@ruby-forum.com 
wrote:
>....Lastly, my code I posted did not convert terms to improper
fractions,...

not to answer your questions, but, i'd probably go a different  route 
...

eg,

require 'rational'
["1 3/4", "-2 1/2", "5/8", "-1/3", "5", "-5"].map do |mix|
  mix.split.map{|x| Rational(x)}
end

=> [ [(1/1), (3/4)],  [(-2/1), (1/2)],  [(5/8)],  [(-1/3)],  [(5/1)],
 [(-5/1)] ]

kind regards -botp
Posted by Derrick B. (dbuckhal)
on 2012-12-21 06:58
botp wrote in post #1089780:
> On Fri, Dec 21, 2012 at 12:59 PM, Derrick B. <lists@ruby-forum.com
> wrote:
>>....Lastly, my code I posted did not convert terms to improper
> fractions,...
>
> not to answer your questions, but, i'd probably go a different  route
> ...
>
> eg,
>
> require 'rational'
> ["1 3/4", "-2 1/2", "5/8", "-1/3", "5", "-5"].map do |mix|
>   mix.split.map{|x| Rational(x)}
> end
>
> => [ [(1/1), (3/4)],  [(-2/1), (1/2)],  [(5/8)],  [(-1/3)],  [(5/1)],
>  [(-5/1)] ]
>
> kind regards -botp

Interesting!  Coming from Perl, I figured there would be a gem to handle
fractions.

edit:  this program was derived from an assignment to create a C++ class
to handle rational numbers, so it went from a C++ class, to a Perl
package, to a Ruby class.  So, everything "by hand"  :)  Personally, I
like coding the underlying methods for practice, I do need to learn more
CPAN and gem capabilities.

Thanks!
Posted by 7stud -- (7stud)
on 2012-12-21 08:38
Derrick B. wrote in post #1089779:
>
> Why is it that when I try to add
> a comment after a line continuation backslash, Ruby says:
>
> ./ratnum.rb:14: syntax error, unexpected $undefined
>     n = ( w == w.abs ) ? \ #
>                           ^
> ./ratnum.rb:15: syntax error, unexpected ':', expecting keyword_end
>
> Ruby should respect my need for comments!  :)
>

See if you can make sense of this line:

result = true ?  \ n  #your comment "true value" : "false value"

which is equivalent to:

result = true ?  \ n
Posted by 7stud -- (7stud)
on 2012-12-21 08:40
> That works, but it needs another "[-]?" in the second group to handle
> negative numerators, or whole numbers:

Right, sorry.  I would try to capture it out front so that I wouldn't 
have to
repeat myself.  By the way, if you haven't played with Rubular, you
should
give it a try:

http://rubular.com/
Posted by 7stud -- (7stud)
on 2012-12-21 08:43
> I got the "??" from Perl, but it seems to not be a problem in Ruby.

I don't see how it is pertinent to your regex.
Posted by Robert Klemme (robert_k78)
on 2012-12-21 11:35
(Received via mailing list)
On Thu, Dec 20, 2012 at 7:23 PM, Derrick B. <lists@ruby-forum.com> 
wrote:
>>     w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [1, $1.to_i, 0]
>>     printf "%4d %4d %4d\n", w, n, d
>>   else
>>     $stderr.puts "No match #{s}"
>>   end
>> end
>>
>> I also spiced the regexp a bit more to be more restrictive.
>
> I am prompting for input, so I would be parsing individual strings and
> not a list of them.

That was just for demonstration purposes.

>  Though I will remember that for future static
> testing.  Also, I and using the "\S+" to handle negative rational
> numbers: "-1 3/4".

There's still a better way to do that then just match everything non
whitespace.  How would you parse ":s9d2++*3h43" as a number?

["1 3/4", "5", '-23', '-23 -4/4'].each do |s|
  puts s

  if %r{\A([-+]?\d+)(?:\s+([-+]?\d+)/(\d+))?\z} =~ s
    w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [1, $1.to_i, 0]
    printf "%4d %4d %4d\n", w, n, d
  else
    $stderr.puts "No match #{s}"
  end
end

Btw, did I mention that I find your variable assignment weird?  I'd 
rather do

["1 3/4", "5", '-23', '-23 -4/4'].each do |s|
  puts s

  if %r{\A([-+]?\d+)(?:\s+([-+]?\d+)/(\d+))?\z} =~ s
    w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [$1.to_i, 0, 1]
    printf "%4d %4d %4d\n", w, n, d
  else
    $stderr.puts "No match #{s}"
  end
end

>> If you like readability then why are you using Perl in the first place?
>> :-)
>
> Because Perl is awesome!

Hm...  It's been a while that I thought that (but I did actually
once).  IMHO Perl has gone over the edge of usefulness long ago.

>  That is why I chose Ruby as my next personal
> choice of languages to learn.

Good choice!

>  I just completed a quarter of Programming
> Language Concepts where I was introduced to Lisp, but was also required
> to use some Python.  I know Python is a fascinatng language, but I am
> not yet a big fan of it.  The final assignment was write a class to work
> with fractions.  It started as a C++ class, then migrated to Perl (for
> fun), and now Ruby (more fun).

:-)

> I attached the two versions, Ruby and Perl.  The Perl version uses a
> "class", also.  Feel free to suggest how to make the Ruby version more
> Ruby-ish!  My goal is to take more advantage of the OO aspects of Ruby,
> and not just have it look like Perl.

I don't have the time right now but you should definitively use class
Rational.  Also your parsing of the command line could be better:

do
  print "Fraction 1: "
  input = gets or break
  f1 = parse_fraction(input)

  print "Fraction 2: "
  input = gets or break
  f2 = parse_fraction(input)

  print "Command: "
  input = gets or break

  case input
  when "A"
    puts f1 + f2
  when "S"
    puts f1 - f2
 ...
 else
   abort "Invalid command: #{input}"
 end

end until cmd == "Q"

puts "Quitting"


You should also not implement #to_string but rather #to_s and then use
string interpolation for constructing your outputs.

Kind regards

robert
Posted by Derrick B. (dbuckhal)
on 2012-12-21 18:58
7stud -- wrote in post #1089800:

> See if you can make sense of this line:
>
> result = true ?  \ n  #your comment "true value" : "false value"
>
> which is equivalent to:
>
> result = true ?  \ n

I can see that, but it is still odd.
Posted by Derrick B. (dbuckhal)
on 2012-12-21 19:19
Robert Klemme wrote in post #1089807:

> That was just for demonstration purposes.
>

Understood.

>
> There's still a better way to do that then just match everything non
> whitespace.  How would you parse ":s9d2++*3h43" as a number?
>
> ["1 3/4", "5", '-23', '-23 -4/4'].each do |s|
>   puts s
>
>   if %r{\A([-+]?\d+)(?:\s+([-+]?\d+)/(\d+))?\z} =~ s
>     w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [1, $1.to_i, 0]
>     printf "%4d %4d %4d\n", w, n, d
>   else
>     $stderr.puts "No match #{s}"
>   end
> end
>

I like that, because it introduces to_i during capture, which was what I
was also trying to figure out.  I have already modified my regex to
something similar to yours.

> Btw, did I mention that I find your variable assignment weird?  I'd
> rather do
>
> ["1 3/4", "5", '-23', '-23 -4/4'].each do |s|
>   puts s
>
>   if %r{\A([-+]?\d+)(?:\s+([-+]?\d+)/(\d+))?\z} =~ s
>     w, n, d = $2 ? [$1.to_i, $2.to_i, $3.to_i] : [$1.to_i, 0, 1]
>     printf "%4d %4d %4d\n", w, n, d
>   else
>     $stderr.puts "No match #{s}"
>   end
> end
>

I will have to search for "weird" in recent posts.  haha!  I do not
doubt it, but for my C++ to Perl to Ruby translation, it was
seamless.

> I don't have the time right now but you should definitively use class
> Rational.  Also your parsing of the command line could be better:
>
> do
>   print "Fraction 1: "
>   input = gets or break
>   f1 = parse_fraction(input)
>
>   print "Fraction 2: "
>   input = gets or break
>   f2 = parse_fraction(input)
>
>   print "Command: "
>   input = gets or break
>
>   case input
>   when "A"
>     puts f1 + f2
>   when "S"
>     puts f1 - f2
>  ...
>  else
>    abort "Invalid command: #{input}"
>  end
>
> end until cmd == "Q"
>
> puts "Quitting"
>
>
> You should also not implement #to_string but rather #to_s and then use
> string interpolation for constructing your outputs.
>
> Kind regards
>
> robert

As I stated as an edit in a previous post, this started as an assignment
to create a C++ class that handles fractions, so I then created a Perl
"class", and now a Ruby class.  So, using "require rational", or "use
bigrat" in Perl, would have defeated the purpose.  I do plan on learning
more about Ruby, and Perl, add-ons.

Thank you all for the input!  I really appreciate being able to post
code and have quality responses.  I am transitioning from a career
(nearly 20 years) in IT, to going to school to get my BS in CS, to then
continue as a programmer.

I'll try not to be a stranger as long as my code is to be considered
strange.  :)
Posted by 7stud -- (7stud)
on 2012-12-21 20:35
...
Posted by Derrick B. (dbuckhal)
on 2012-12-22 04:55
7stud -- wrote in post #1089801:
>By the way, if you haven't played with Rubular, you
> should
> give it a try:
>
> http://rubular.com/

I have found that.  Good tool to use.

Also, I am still trying to wrap my head around the line terminating 
error I showed you.  I want to try other scenarios besides conditional 
operators to see what happens.

Lastly, I reduced my assignment statement to two lines:

    %r{(?:([-]?\d+)\s*)??([-]?\d+)(/)(\d+)}xms =~ frac
    w, n, d = $3 ? [$1.to_i, $2.to_i, $4.to_i] : [1, frac.to_i, 0]

... which adds the slash check, rather than using a separate regex. 
Probably still "weird", but that's ok.  :)

I think I need to start a new thread with new material.  20+ entries is 
probably enough.  For now, I'm on chapter nine of "The Ruby Programming 
Language", which is an in-depth tour of Ruby syntax.  Good stuff.
Posted by Hans Mackowiak (hanmac)
on 2012-12-22 07:54
dbuckhal what about this?

w,n,d = 1,frac,0 unless 
%r{(?:(?<w>[-]?\d+)\s*)??(?<n>[-]?\d+)/(?<d>\d+)}xms =~ frac
w,n,d = w.to_i,n.to_i,d.to_i

with that you do not need the $vars
Posted by 7stud -- (7stud)
on 2012-12-22 08:40
> Also, I am still trying to wrap my head around the line terminating
> error I showed you.

Explain in detail what you think a \ at the end of the line does?  Well, 
maybe we need to get more basic than that: Do you know what a newline 
is?
Posted by Bartosz DziewoƄski (matmarex)
on 2012-12-22 13:25
(Received via mailing list)
On Sat, 22 Dec 2012 08:40:58 +0100, 7stud -- <lists@ruby-forum.com> 
wrote:
> Explain in detail what do you think a \ at the end of the line does?

It allows one to continue a line that would otherwise be terminated. 
Contrived example:

a = 5
+ 2
puts a
# => 5

a = 5 \
+ 2
puts a
# => 7

It wasn't necessary in OP's example, but I also think it should work 
there.
Posted by Robert Klemme (robert_k78)
on 2012-12-22 16:21
(Received via mailing list)
On Fri, Dec 21, 2012 at 7:19 PM, Derrick B. <lists@ruby-forum.com> 
wrote:
> Robert Klemme wrote in post #1089807:

>>     $stderr.puts "No match #{s}"
>>   end
>> end
>
> I will have to search for "weird" in recent posts.  haha!  I do not
> doubt it, but for my C++ to Perl to Ruby translation, it was
> seamless.

:-)  What I meant by weird was that I would have the first variable
always store the integer number, the second the numerator and the
third the denominator.  With your numbering scheme you need to
evaluate the third value against 0 to detect what kind of number you
have.  With my scheme you can treat all parsed input equally and you
won't have a division by zero (unless the user entered 0 as last
number).

> As I stated as an edit in a previous post, this started as an assignment
> to create a C++ class that handles fractions, so I then created a Perl
> "class", and now a Ruby class.  So, using "require rational", or "use
> bigrat" in Perl, would have defeated the purpose.  I do plan on learning
> more about Ruby, and Perl, add-ons.

Ah, yes of course that makes a whole lot of sense.  I must have
forgotten in between.

Btw, I have a blog posting about creating numerical classes in Ruby:
http://blog.rubybestpractices.com/posts/rklemme/01...

You might want to read the previous article first:
http://blog.rubybestpractices.com/posts/rklemme/01...

> Thank you all for the input!  I really appreciate being able to post
> code and have quality responses.  I am transitioning from a career
> (nearly 20 years) in IT, to going to school to get my BS in CS, to then
> continue as a programmer.

Good!  Please make sure that you do not miss the part about algorithms
and data structures.  I consider that one of the more important parts
in CS.

> I'll try not to be a stranger as long as my code is to be considered
> strange.  :)

:-)

Kind regards

robert
Posted by Derrick B. (dbuckhal)
on 2012-12-22 18:15
7stud -- wrote in post #1089925:
>> Also, I am still trying to wrap my head around the line terminating
>> error I showed you.
>
> Explain in detail what you think a \ at the end of the line does?  Well,
> maybe we need to get more basic than that: Do you know what a newline
> is?

My understanding, from a C/C++ background, is that the '\' allows for
continuation of the current line.  Combine that with my knowledge of
comments (// and /* */ in C/C++) should allow for anything following
that to be "ignored".  Perl does not behave as Ruby did when I did the
very same thing.  So, maybe I took my assumption of those to personal
ideas and definitions and expected too much from Ruby?

I so also understand that the '\' is an escape character to allow for
various things to happen:  newlines, tabs, characters to have different
meanings in strings, etc...

So, please enlighten me as to your definition, or a link to an official
definition of a newline, line continuation indicator, and anything else
that would be useful.

Thanks,

Derrick
Posted by Derrick B. (dbuckhal)
on 2012-12-22 18:17
Robert Klemme wrote in post #1089946:
>
> Good!  Please make sure that you do not miss the part about algorithms
> and data structures.  I consider that one of the more important parts
> in CS.
>

Yes, Data Structure out of the way (B+), and Algorithms next quarter, 
along with OOP design, Systems Programming, and 15lbs of stress to 
accumulate.  :D
Posted by 7stud -- (7stud)
on 2012-12-22 23:14
Derrick B. wrote in post #1089954:
>
> I so also understand that the '\' is an escape character
>

Okay.  Now what does this produce:

"\\n"
Posted by 7stud -- (7stud)
on 2012-12-22 23:52
> an official definition of a newline

Inside a ruby program, a newline is defined to be the string: "\n".

However, anytime you hit <RETURN> in your text editor an invisible
newline is entered into the text you are typing.  All text is just one
long continuous string of characters--where some of the characters may
be spaces, tabs, or newlines.  But text editors do something special 
when
they display a newline--they skip down to the next line to display the
text that follows a newline.
Posted by Eric Christopherson (echristopherson)
on 2012-12-23 02:11
(Received via mailing list)
I just wanted to point out that all of 7stud's messages (as far as I
know) in this thread have gotten truncated by the time they reached my
Gmail inbox. I'm not sure if this is a problem with Gmail or
ruby-forum.com or the list.

For instance, this is all I got for 7stud's most recent message:

On Sat, Dec 22, 2012 at 4:52 PM, 7stud -- <lists@ruby-forum.com> wrote:
>> an official definition of a newline
>
> Inside a ruby program, a newline is defined to be the string: "\n".
>
> --
> Posted via http://www.ruby-forum.com/.
>

But this shows up at <http://www.ruby-forum.com/topic/4409205#new>:
Posted by Eric Christopherson (echristopherson)
on 2012-12-23 02:27
(Received via mailing list)
On Sat, Dec 22, 2012 at 7:09 PM, Eric Christopherson
<echristopherson@gmail.com> wrote:
> I just wanted to point out that all of 7stud's messages (as far as I
> know) in this thread have gotten truncated by the time they reached my
> Gmail inbox.

Maybe I was exaggerating about it being "all of" them. Now that I've
looked I only see a few.
Posted by Derrick B. (dbuckhal)
on 2012-12-23 08:01
7stud -- wrote in post #1089965:
>> an official definition of a newline
>
> Inside a ruby program, a newline is defined to be the string: "\n".
>
> However, anytime you hit <RETURN> in your text editor an invisible
> newline is entered into the text you are typing.  All text is just one
> long continuous string of characters--where some of the characters may
> be spaces, tabs, or newlines.  But text editors do something special
> when
> they display a newline--they skip down to the next line to display the
> text that follows a newline.

Thanks, but I am no longer trying to wrap my head around it.  I tested
it in some C++ and Perl code, did not work, so I'm fine with proven
failed results.  I only began this query because I did not understand
why Ruby would not allow a conditional to span the lines as such before
I even introduced comments:

    n = ( w == w.abs ) \
        ? n + w * d
        : -1 * ( n - w * d ) if d != 0

...without putting a durn slash in the first line.  Without it, I get:

./ratnum.rb:17: warning: invalid character syntax; use ?\s
./ratnum.rb:17: syntax error, unexpected '?', expecting keyword_end
        ? n + w * d                   ...
         ^
./ratnum.rb:18: syntax error, unexpected ':', expecting keyword_end
        : -1 * ( n - w * d ) if d != 0...
         ^
I do understand that line termination, or an optional semi-colon, 
completes a statement in Ruby.

Perl does just fine without the slash:

    $n = ( $w == abs($w) )
        ? $n + $w * $d
        : -1 * ( $n - $w * $d ) if $d;

I appreciate your effort, but am ready to move on to something else to 
talk about.  heh
Posted by 7stud -- (7stud)
on 2012-12-23 23:15
Derrick B. wrote in post #1089990:
>
> Perl does just fine without the slash:
>
>     $n = ( $w == abs($w) )
>         ? $n + $w * $d
>         : -1 * ( $n - $w * $d ) if $d;
>
>

And you have no idea why that is?  The perl parser knows that a
statement has ended when it sees a semi-colon.  How does the ruby parser
know when a statement has ended?

> I appreciate your effort, but am ready to move on to something
> else to talk about.

Sure.
Posted by Derrick B. (dbuckhal)
on 2012-12-23 23:40
7stud -- wrote in post #1090043:

>
> And you have no idea why that is?  The perl parser knows that a
> statement has ended when it sees a semi-colon.  How does the ruby parser
> know when a statement has ended?
>

Ruby is similar to Python in that it uses line termination, unless you 
indicate an implied line continuation.

a = b +
c

implies continuation, whereas

a = b
+ c

does not.

You can also use a semicolon in Ruby to end a statement, but usually 
that is when you put multiple statements on one line.

I cannot wait to take the Compiler Design class, because these details 
will  be exactly what I need to take into consideration when creating my 
own language parser.
Posted by Siep Korteling (steenslag)
on 2012-12-26 00:05
Derrick B. wrote in post #1089888:
(...)
>
> As I stated as an edit in a previous post, this started as an assignment
> to create a C++ class that handles fractions, so I then created a Perl
> "class", and now a Ruby class.  So, using "require rational", or "use
> bigrat" in Perl, would have defeated the purpose.  I do plan on learning
> more about Ruby, and Perl, add-ons.

Just to clear things up, since Ruby 1.9 Rational is not a gem nor in 
Standard Lib, it is in Ruby core. For instance, this works without 
requiring anything:

 puts "1/40".to_r * "2/3".to_r #=> 1/60

and botp's code runs without the require 'rational' on 1.9. Nothing 
wrong with reinventing a wheel for learning purposes however.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.