# Need help converting Perl to Ruby (detecting integers and de

**URL:** <https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961>\
**Category:** Ruby\
**Created:** [March 15, 2007, 10:40pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961 "2007-03-15T22:40:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 10:40pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/1 "2007-03-15T22:40:44Z")

</div>

I am trying to convert a Perl script to Ruby and have been having some  
difficulty along the way (mostly because I don’t know Perl).

## I am currently stumped on one particular line in the old Perl script:

## foreach (@rawfields) {if ($\_ \> 0){$\_ = int($\_\*100)/100}}

## Background context: @rawfields is an array that holds the contents of an imported line from a text file. Here are some sample lines from the input file:

## “0” “0” “0” “0” “0” “0” “Bar” “5.66666” “0” “3.566662” “1.383332” “6” “0” “Foo”

My guess is that the Perl line iterates through each of the elements  
in the array and rounds any integers to 2 decimals.

This raises a few problems for me.

1. How can I easily tell if the (string) value in each array element  
is an integer or has a decimal value?

## =\> The desired output for text file line 2 is :

## “5.67” “0” “3.57” “1.38” “6” “0” “Foo”

## I tried the following in Ruby:

## @rawfields.each\_index do |x| if ( @rawfields[x].to\_f \> 0 ) @rawfields[x] = ( (( @rawfields[x].to\_f \* 100 ).round.to\_i ).to\_f / 100 ).to\_s end end

## But it produces the following output:

## “5.67” “0” “3.57” “1.38” “6.0” “0” “Foo”

…which is close, but not quite what I want. My output file now has  
values like 1.0, 5.0, 62.0, etc. If it’s an integer, I don’t want to  
see the decimal.

Can anyone suggest an improvement to my code or a better translation  
from Perl?

TIA. Paul.

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 10:56pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/2 "2007-03-15T22:56:46Z")

</div>

On 15.03.2007 22:39, Paul wrote:

> the input file:
> 
> 1. How can I easily tell if the (string) value in each array element  
> @rawfields.each\_index do |x|
> 
> * * *
> 
> …which is close, but not quite what I want. My output file now has  
> values like 1.0, 5.0, 62.0, etc. If it’s an integer, I don’t want to  
> see the decimal.
> 
> Can anyone suggest an improvement to my code or a better translation  
> from Perl?
> 
> TIA. Paul.

How about

irb(main):005:0\> fields = %w{5.6666 0 Foo}  
=\> [“5.6666”, “0”, “Foo”]  
irb(main):006:0\> fields.map {|v| sprintf("%4.2f", Float(v)) rescue v}  
=\> [“5.67”, “0.00”, “Foo”]

This uses the fact that Float() will throw if the string is not a valid  
number. If you really need “0” instead of “0.00” you could apply  
another test. If you need the quotes you could do

irb(main):008:0\> puts fields.map {|v| (sprintf("%4.2f", Float(v)) rescue  
v).inspect}.join(" ")  
“5.67” “0.00” “Foo”

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 10:59pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/3 "2007-03-15T22:59:47Z")

</div>

On 3/16/07, Paul [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ## Background context: @rawfields is an array that holds the contents of an imported line from a text file. Here are some sample lines from the input file:
> 
> “0” “0” “0” “0” “0” “0” “Bar”  
> “5.66666” “0” “3.566662” “1.383332” “6” “0” “Foo”

> > rawfields = [“5.66666”, “0”, “3.566662”, “1.383332”, “6”, “0”, “Foo”]  
> > =\> [“5.66666”, “0”, “3.566662”, “1.383332”, “6”, “0”, “Foo”]

> > rawfields.map {|field| “%0.2f” % Float(field) rescue field}  
> > =\> [“5.67”, “0.00”, “3.57”, “1.38”, “6.00”, “0.00”, “Foo”]

Breaking it up,

Float(string) either converts a string to a float, or raises an  
exception if it cannot be so converted.

% is the sprintf operator, so “%0.2f” % float rounds the float to two  
decimal places and interpolates it into the string. Note that it does  
round properly, as per the printf spec, rather than truncating.

finally, expression1 rescue expression2 means return expression1,  
unless it raises an exception in which case return expression2

martin

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 11:06pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/4 "2007-03-15T23:06:48Z")

</div>

On 3/16/07, Martin DeMello [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> =\> [“5.66666”, “0”, “3.566662”, “1.383332”, “6”, “0”, “Foo”]
> 
> > > rawfields.map {|field| “%0.2f” % Float(field) rescue field}  
> > > =\> [“5.67”, “0.00”, “3.57”, “1.38”, “6.00”, “0.00”, “Foo”]

oops - missed the fact that you didn’t want integers converted into  
decimals. Best way I can think of is a two level try/rescue-try/rescue

> > rawfields.map {|field| “%d” % Integer(field) rescue “%0.2f” %  
> > Float(field) rescue field}  
> > =\> [“5.67”, “0”, “3.57”, “1.38”, “6”, “0”, “Foo”]

More explicitly

rawfields.map do |field|  
begin  
“%d” % Integer(field)  
rescue  
begin  
“%0.2f” % Float(field)  
rescue  
field  
end  
end  
end

martin

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 11:04pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/5 "2007-03-15T23:04:47Z")

</div>

Hi –

On 3/15/07, Paul [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> the input file:
> 
> 1. How can I easily tell if the (string) value in each array element  
> @rawfields.each\_index do |x|
> 
> * * *
> 
> …which is close, but not quite what I want. My output file now has  
> values like 1.0, 5.0, 62.0, etc. If it’s an integer, I don’t want to  
> see the decimal.
> 
> Can anyone suggest an improvement to my code or a better translation  
> from Perl?

See if this helps:

@rawfields.map! do |x|  
if x =~ /^\d+.\d+$/  
“%.2f” % x  
else  
x  
end  
end

David

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 15, 2007, 11:22pm UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/6 "2007-03-15T23:22:51Z")

</div>

rawfields.map { |f| f.to\_f.to\_s == f ? “%0.2f” % f.to\_f : f }  
=\> [“5.67”, “0”, “3.57”, “1.38”, “6”, “0”, “Foo”]

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 16, 2007, 3:56am UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/7 "2007-03-16T03:56:15Z")

</div>

That is brilliant! Thank you, Jon! Of all the good suggestions  
posted, I like this one best. You guys all rock! Thanks so much for  
the responses.

Cheers! Paul. =)

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 16, 2007, 4:23am UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/8 "2007-03-16T04:23:18Z")

</div>

On 3/16/07, Paul [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> That is brilliant! Thank you, Jon! Of all the good suggestions  
> posted, I like this one best. You guys all rock! Thanks so much for  
> the responses.
> 
> Cheers! Paul. =)
> 
> On Mar 15, 6:22 pm, Jon G. wrote:
> 
> > rawfields.map { |f| f.to\_f.to\_s == f ? “%0.2f” % f.to\_f : f }

rawfields.map{|f| Integer(f) rescue Float(f) rescue f}

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [March 18, 2007, 3:01am UTC](https://www.ruby-forum.com/t/need-help-converting-perl-to-ruby-detecting-integers-and-de/88961/9 "2007-03-18T03:01:28Z")

</div>

Hi –

On 3/15/07, Michael F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> rawfields.map{|f| Integer(f) rescue Float(f) rescue f}

That doesn’t produce the desired output.

David
