Forum: Ruby how remove puts inside method?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Carlos D. (Guest)
on 2006-01-05 18:00
I have a method (process_transaction) that uses puts to output a result.
Now I wanted to remove puts, so I could further process the result of
the method before printing it. But I can't get it to  work ...

# method checks what key matches with string
# and adds additional info to each string def process_transaction
(line_of_file)

	if get_money(line_of_file) < 0

		Ausgabekonten.any? { |key, konto|
			if key =~ line_of_file
				kontonummer = extract_four_digit(konto)
				puts line_of_file.chomp + "	\"" + key.to_s + "\"	" +
kontonummer.to_s + "	1200" + "	AUSGABE"
				break true
			end
		} or  warn line_of_file.chomp + "	(no key)	\"\"	\"\"	\"\"
AUSGABE_NO_KEY"

	else

		Einnahmekonten.any? { |key, konto|
			if key =~ line_of_file
				kontonummer = extract_four_digit(konto)
				puts line_of_file.chomp + "	\"" + key.to_s + "\"" + "	1200	" +
kontonummer.to_s + "	EINNAHME"
				break true
			end
		} or  warn line_of_file.chomp + "	(no key)	\"\"	\"\"	\"\"
EINNAHME_NO_KEY"

	end

end

# apply process_transaction to each line of the transactions array

transactions.each do |member|
	process_transaction(member)
end
Carlos D. (Guest)
on 2006-01-05 18:05
For example I would like to remove puts from the process_transaction
method and the do this:

transactions.each do |member|
	puts process_transaction(member)
end

(sorry for the messy line breaks!)
Kevin O. (Guest)
on 2006-01-05 18:20
You could just mash the output into one long string...

output = ""
...
output << line_of_file.....
...
return output

Then return the string at the end of the function.
You may need to tack on some linefeeds at the end of each line.
Robert K. (Guest)
on 2006-01-05 18:44
(Received via mailing list)
Carlos Delmar wrote:
> For example I would like to remove puts from the process_transaction
> method and the do this:
>
> transactions.each do |member|
> puts process_transaction(member)
> end
>
> (sorry for the messy line breaks!)

I'm not really sure what you're up to.  Can you elaborate?  The only
thing
that comes to mind is that you probably want to use #each instead of
#any?
because the latter is merely for identifying something and it does short
circuit (i.e. stop once the first block returns true).

Kind regards

    robert
unknown (Guest)
on 2006-01-05 18:44
(Received via mailing list)
On Fri, 6 Jan 2006, Carlos Delmar wrote:

> Posted via http://www.ruby-forum.com/.
it's not puts that you need to mess with - it's stdout that needs
capturing:

     harp:~ > cat a.rb
     require "yaml"
     require "stringio"

     def buffering_stdout
       stdout, sio = $stdout, StringIO::new
       begin
         $stdout = sio
         yield
         sio.rewind
         sio.read
       ensure
         $stdout = stdout
       end
     end

     stdout =
       buffering_stdout do
         puts 42
         p 42
         printf "%d\n", 42
       end

     y "stdout" => stdout



     harp:~ > ruby a.rb
     stdout: |
       42
       42
       42


regards.

-a
Carlos D. (Guest)
on 2006-01-05 22:13
> I'm not really sure what you're up to.  Can you elaborate?

I'd like the output of process_transaction as a long string. But I don't
completely understand the post from Kevin:

> output = ""
> ...
> output << line_of_file.....
> ...
> return output

where does this go?

If the method works I would like to apply it to each line of
transactions array and output the result to a new file.

here's the latest version of the script:
http://rafb.net/paste/results/D632e199.html
Robert K. (Guest)
on 2006-01-06 10:49
(Received via mailing list)
Carlos Delmar wrote:
>
> where does this go?
>
> If the method works I would like to apply it to each line of
> transactions array and output the result to a new file.
>
> here's the latest version of the script:
> http://rafb.net/paste/results/D632e199.html

The parts after "or" will never be called because each returns the
Enumerable.  You have several options; one of is replacing "puts" by
"return" and remobing "or".  In the calling block you can then process
the
string return value as needed.  For example you can do

puts transactions.map do |member|
  process_transaction(member)
end

This will print each result on a single line.  Or you can do

puts transactions.map do |member|
  process_transaction(member)
end.join

to get a single long string.

There are lots of alternatives...

Kind regards

    robert
Carlos D. (Guest)
on 2006-01-06 14:05
thanks Robert ... but it did not work out ...

>The parts after "or" will never be called because each returns the Enumerable.

that was right, i replaced 'puts' after 'or' with 'warn' (which I had
removed by mistake)

Fnd a working script with some data here:

http://rafb.net/paste/results/2yJH7J28.html

BUT: I still would like to remove 'puts' and 'warn' in the
process_transaction method and would much prefer to 'puts' a resulting
string later in the transactions.each statement (or write that to a
file).
Lyndon S. (Guest)
on 2006-01-06 14:32
(Received via mailing list)
>
> BUT: I still would like to remove 'puts' and 'warn' in the
> process_transaction method and would much prefer to 'puts' a resulting
> string later in the transactions.each statement (or write that to a
> file).


A simple solution is you can allways stuff your output in an array.

out = []

out << "Message #{msg}"

out.each { |line| puts line }

You know you can return multiple values from a method right?

return out, retCode, a,b,c
Kevin O. (Guest)
on 2006-01-06 14:44
Carlos Delmar wrote:
>> I'm not really sure what you're up to.  Can you elaborate?
>
> I'd like the output of process_transaction as a long string. But I don't
> completely understand the post from Kevin:
>
>> output = ""
>> ...
>> output << line_of_file.....
>> ...
>> return output
>
> where does this go?
>
> If the method works I would like to apply it to each line of
> transactions array and output the result to a new file.
>
> here's the latest version of the script:
> http://rafb.net/paste/results/D632e199.html

Just put this type of structure in whichever function you are trying to
capture the output of.

first line creates a string object, then you use the '<<' to append
output to that string, then you do something with the string when you
are done.
Carlos D. (Guest)
on 2006-01-06 16:06
thanks a lot, now it works: http://rafb.net/paste/results/8FsA6E62.html

still I don't really understand what the ouput variable does. And why
simply removing the output statements does not work:
http://rafb.net/paste/results/hjON3o64.html

:/?
Robert K. (Guest)
on 2006-01-06 16:23
(Received via mailing list)
Carlos Delmar wrote:
> http://rafb.net/paste/results/2yJH7J28.html
>
> BUT: I still would like to remove 'puts' and 'warn' in the
> process_transaction method and would much prefer to 'puts' a resulting
> string later in the transactions.each statement (or write that to a
> file).

Somehow I find your design a bit contrived: you store your meta data in
strings and then have to extract what you need.  It would be much
cleaner
and simpler to directly store it, for example in arrays stored in
hashes:


#!/usr/bin/ruby

# script should check if one of the keys in Ausgabekonten or
Einnahmekonten hash
# can be found in each line of the transactions array.
# If it does, it should print the matching key and value of the
Ausgabekonten hash.
# If it does not, it should print a warning.

Ausgabekonten = {
  /BIO COMPANY /  =>  ["1805", "Bio Company", "Lebensmittel"],
  /KAISERS /      =>  ["1805", "Bio Company", "Lebensmittel"],
  /VINOTRIA /     =>  ["1805", "Bio Company", "Lebensmittel"],
}

Einnahmekonten = {
  /CLIENT_ONE/    =>  ["8300", "Client 1", "Erlöse 7% Ust"],
  /CLIENT_TWO/    =>  ["8300", "Client 2", "Erlöse 7% Ust"],
}

transactions = [
  '"30.12.2005" "30.12.2005"  "VINOTRIA ITALIAN VINE STORE" "-20,00"
"EUR" "*"',
  '"30.12.2005" "30.12.2005"  "KAISERS FOOD"  "-140,00" "EUR" "*"',
  '"30.12.2005" "30.12.2005"  "SOMETHING NEW" "900,00"  "EUR" "*"',
  '"30.12.2005" "30.12.2005"  "CLIENT_ONE Job XY" "2.000,00"  "EUR"
"*"',
  '"30.12.2005" "30.12.2005"  "I DONT REMEMBER" "-300,00" "EUR" "*"',
  '"30.12.2005" "30.12.2005"  "CLIENT_TWO Job XY" "1.500,00"  "EUR" "*"'
  ]

# method finds money snippet in string and converts it into a string
def find_money_string (string)

string.scan(/\"-?[0123456789]{0,3}.[0123456789]{0,3},[0-9][0-9]\"/).to_s.c
hop[1..-1]
end

# method changes string from german format (,.) to float (.)
def format_number(string)
  string.tr(".", ";").tr(",", ".").tr(";", "").to_f
end

# extracts the 4 digit number from a string
def extract_four_digit(string)
  string.to_s.scan(/[0-9][0-9][0-9][0-9]/)
end

# method extracts money of string
def get_money (string)
  x = find_money_string(string)
  format_number(x)
end

def parse(line)
  line.scan(/"([^"]*)"/).map {|m| m[0]}
end

# method checks what key matches with string and adds additional info to
each string
def process_transaction (line_of_file)
  date1, date2, text, amount, currency, rest = parse line_of_file
  amount = amount.tr('.,', '_.').to_f

  if amount < 0

   key, info =  Ausgabekonten.find { |key, konto| key =~ line_of_file }

   if info
     print line_of_file.chomp, " \"", info[1], "\" \"", info[0],
"1200\n"
   else
     warn line_of_file.chomp + "        (no
       --      --      --"
   end

  else

   key, info =  Einnahmekonten.find { |key, konto| key =~ line_of_file }

   if info
        print line_of_file.chomp, " \"", info[1], "\" \"1200\" ",
info[0],
"\n"
   else
        warn line_of_file.chomp + "     (no
       --      --      --"
   end
  end

end

# apply process_transaction to each line of the transactions array
transactions.each do |member|
  process_transaction(member)
end

HTH

    robert
Kevin O. (Guest)
on 2006-01-06 19:34
Carlos Delmar wrote:
> thanks a lot, now it works: http://rafb.net/paste/results/8FsA6E62.html
>
> still I don't really understand what the ouput variable does. And why
> simply removing the output statements does not work:
> http://rafb.net/paste/results/hjON3o64.html
>
> :/?

"output" is just a string variable with a confusing name, you could call
it anything you want.  It just holds the output until you are ready to
return.
Carlos D. (Guest)
on 2006-01-07 01:58
Thanks Robert! This works beautifull!

I have one question though. What exactly does the m[0]? Why zero?

def parse(line)
	line.scan(/"([^"]*)"/).map {|m| m[0]}
end
This topic is locked and can not be replied to.