Method too long problem

I am converting a spreadsheet into ruby so that it may be executed as part
of a bigger system. This has worked well for sheets with only 1,000s of
cells. There is a problem with sheets that have nearly 200,000 cells. The
program blows up when it runs.

Here is a simplified example:

def zxc(value)
  x0 = value
  x1 = x0 + 1
  x2 = x1 + 1
  x3 = x2 + 1
  x4 = x3 + 1
  x5 = x4 + 1
  x6 = x5 + 1
  x7 = x6 + 1
  x8 = x7 + 1

  # More of the same until...

  x99995 = x99994 + 1
  x99996 = x99995 + 1
  x99997 = x99996 + 1
  x99998 = x99997 + 1
  x99999 = x99998 + 1
  x100000 = x99999 + 1
  return x100000
end

puts zxc(0)

This will run without error and returns 100000 as expected. But if the code
gets larger, such as:

  x149995 = x149994 + 1
  x149996 = x149995 + 1
  x149997 = x149996 + 1
  x149998 = x149997 + 1
  x149999 = x149998 + 1
  x150000 = x149999 + 1
  return x150000
end

puts zxc(0)

The result is:

x2.rb:150006:in `<main>': stack level too deep (SystemStackError)

The program is linear and does not iterate or recurse. Is there a way round
this limit?

I am converting a spreadsheet into ruby so that it may be executed as part
of a bigger system. This has worked well for sheets with only 1,000s of
cells. There is a problem with sheets that have nearly 200,000 cells. The
program blows up when it runs.

Wait, so you're using one local variables for each cell?

def zxc(value)
  x0 = value
  x1 = x0 + 1

<snip>

I suggest you use an array, instead; that way you only have one
local variable on the stack, and the rest is in the heap (almost
always bigger than the stack, the heap can use all the memory
your user can allocate)

Naively, it'd be the same number of lines:

  def zxc(value)
    x[0] = value
    x[1] = x[0] + 1
    x[2] = x[1] + 1
    ...
    x[200000] = x[199999] + 1
  end

But, you can vastly simplify it with a loop and not need so
many lines of code:

  def zxc(value)
    x =
    x[0] = value
    (1..200_000).each do |i|
      x[i] = x[i - 1] + 1
    end
    x.last
  end

x2.rb:150006:in `<main>': stack level too deep (SystemStackError)

The program is linear and does not iterate or recurse. Is there a way round
this limit?

Is there any reason you're not using an array and really need so
many local variables?

If so, you can try increasing the stack sizes for
RUBY_THREAD_VM_STACK_SIZE and RUBY_THREAD_MACHINE_STACK_SIZE
as documented in the ruby(1) manpage since Ruby 2.2,
but I really don't think you need so many local variables.

···

Peter Hickman <peterhickman386@googlemail.com> wrote:

Use an array.

Marvin

···

On Sun, May 07, 2017 at 11:34:22AM +0100, Peter Hickman wrote:

The program is linear and does not iterate or recurse. Is there a way round
this limit?

--
Blog: https://www.guelkerdev.de
PGP/GPG ID: F1D8799FBCC8BC4F

ulimit -a

eg try
ulimit -s 123456

kind rgards
--botp

···

On Sun, May 7, 2017 at 6:34 PM, Peter Hickman <peterhickman386@googlemail.com> wrote:

x2.rb:150006:in `<main>': stack level too deep (SystemStackError)
The program is linear and does not iterate or recurse. Is there a way round
this limit?

There is no reason for using one variable per cell, it just worked out that
way. I will try it with an array.

TBH it never occurred to me to use an array but it makes sense.

Thanks for that

Depending on the sparseness of the sheet even a Hash might make sense.
Whatever you do I would abstract the storage in a class of it's own
with methods that allow proper indexing. Then you can fiddle with the
internal storage structure and not affect the remainder of the
program.

Kind regards

robert

···

On Sun, May 7, 2017 at 2:39 PM, Peter Hickman <peterhickman386@googlemail.com> wrote:

There is no reason for using one variable per cell, it just worked out that
way. I will try it with an array.

TBH it never occurred to me to use an array but it makes sense.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/