一个“if”语句句柄可以有多少个“&&”?

时间:2020-12-08 14:31:06

I have the following code:

我有以下代码:

if @if_tannin_true && @if_acid_true && @if_alcohol_true && @if_body_true #I would like to add this: && @if_fruit_true #&& @if_fruit_character_true && @if_non_fruit_true && @if_organic_earth_true && @if_inorganic_earth_true && @if_wood_true

  y = 0
  while y < @grapes[i].testables.count
    @result << @grapes[i].testables[y].name
    y+=1
  end
end

I realized that an if statement using four "&&"s works fine, but one with a fifth will not. How could I handle that?

我意识到,如果用四个“&&”的句子可以很好,但是有五分之一的句子就不行。我怎么处理呢?


Edit: It now works. I just restarted the server. Good to know that we can use as many "&&"s as needed.

编辑:它现在。我刚刚重启服务器。很高兴知道我们可以根据需要使用尽可能多的“&&”。

3 个解决方案

#1


8  

Interesting question!

有趣的问题!

Short answer

Between 5000 and 10000, depending on your system.

在5000到10000之间,这取决于你的系统。

Theory

You could create a string with many true && true && true && ... and evaluate it.

您可以创建一个字符串与许多真&真&真&真&&…和评估。

  • If it returns true, you can add some more &&s.
  • 如果返回true,您可以添加更多的&&s。
  • If it fails with a SystemStackError or even a segmentation fault, you'll need to remove some &&s.
  • 如果它在系统堆栈错误甚至分割错误中失败,您将需要删除一些& &&s。

Since it can crash, you need to write 2 different scripts in order to prevent the main loop from also crashing.

由于它可能崩溃,您需要编写两个不同的脚本,以防止主循环也崩溃。

bsearch finds the limit as fast as possible, without having to iterate over every single possiblity.

bsearch尽可能快地找到极限,而不必遍历每一种可能。

Code

many_ands.rb

# many_ands.rb
many_ands = (['true'] * (ARGV[0].to_i + 1)).join(' && ')
eval(many_ands)

max_ands.rb

big_number = 100_000

max_ands = (0..big_number).bsearch do |i|
  print "Testing #{i} : "
  result = system("ruby many_ands.rb #{i}")
  puts result ? 'Fine' : "Too many &&'s"
  puts
  !result
end

puts "Max number of &&'s without exception : #{max_ands - 1}"

It outputs:

输出:

Testing 50000 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 25000 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 12500 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 6250 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 3125 : Fine

Testing 4688 : Fine

Testing 5469 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5079 : Fine

Testing 5274 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5177 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5128 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5104 : Fine

Testing 5116 : Fine

Testing 5122 : Fine

Testing 5125 : Fine

Testing 5127 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5126 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Max number of &&'s without exception : 5125

It depends on the system : On my Linux VM, it returned 5125. On a server, it returned 7930.

这取决于系统:在我的Linux VM上,它返回5125。在服务器上,它返回7930。

Results vary a bit from one run to the other, even on the same system.

结果在一次运行到另一次运行时有所不同,即使在相同的系统上也是如此。

eval or &&?

Where does the limitation come from? Is it from the string length passed to eval or does it come from the number of &&s?

限制从何而来?是从传递给eval的字符串长度,还是来自&&s的数量?

By modifying many_ands.rb, we now pass a big string to eval with many small expressions instead of one huge && expression:

通过修改many_ands。rb,我们现在传递一个大字符串,用许多小的表达式来计算,而不是一个大的&表达式:

many_ands = (['true'] * (ARGV[0].to_i + 1)).join(';')
eval(many_ands)

The main loop outputs:

主循环输出:

Testing 5000000 : Fine

Testing 7500000 : Fine

Testing 8750000 : Fine

Testing 9375000 : Fine

Testing 9687500 : Fine

Testing 9843750 : Fine

Testing 9921875 : Fine

Testing 9960938 : Fine

Testing 9980469 : Fine

Testing 9990235 : Fine

Testing 9995118 : Fine

Testing 9997559 : Fine

Testing 9998780 : Fine

Testing 9999390 : Fine

Testing 9999695 : Fine

Testing 9999848 : Fine

Testing 9999924 : Fine

Testing 9999962 : Fine

Testing 9999981 : Fine

Testing 9999991 : Fine

Testing 9999996 : Fine

Testing 9999998 : Fine

Testing 9999999 : Fine

Testing 10000000 : Fine

max_and.rb:11:in `<main>': undefined method `-' for nil:NilClass (NoMethodError)

It seems the limitation does come from the number of &&s in the expression. With 10 million true;..., the string passed to eval is 50MB big.

似乎限制来自于表达式中的&&s的数量。1000万真的,…,传递给eval的字符串是50MB大。

#2


4  

I realized that the if statement using 4 && works fine but when I start adding a fifth it will not.

我意识到使用4 &&的if语句是有效的,但是当我开始添加第五个时,它就不能了。

There is no limit to the number of && you use in a statement. So it will work with 4, 5, 100.

在语句中使用&& &的数量没有限制。它对4,5,100都成立。

It fails because some of the conditions are falsey.

它失败了,因为有些条件是不稳定的。

#3


3  

&& is a boolean operator. There is no theoretical limit as to how many if statements it can hold.

&是一个布尔运算符。对于它能容纳多少个if语句,没有理论上的限制。

Using lots in a single statement could be considered a code smell in Ruby, but there's no technical reason why you cannot do it.

在一个语句中使用lot可以被认为是Ruby中的代码味道,但是没有任何技术原因可以解释为什么不能这样做。

What error are you getting?

你犯了什么错误?

#1


8  

Interesting question!

有趣的问题!

Short answer

Between 5000 and 10000, depending on your system.

在5000到10000之间,这取决于你的系统。

Theory

You could create a string with many true && true && true && ... and evaluate it.

您可以创建一个字符串与许多真&真&真&真&&…和评估。

  • If it returns true, you can add some more &&s.
  • 如果返回true,您可以添加更多的&&s。
  • If it fails with a SystemStackError or even a segmentation fault, you'll need to remove some &&s.
  • 如果它在系统堆栈错误甚至分割错误中失败,您将需要删除一些& &&s。

Since it can crash, you need to write 2 different scripts in order to prevent the main loop from also crashing.

由于它可能崩溃,您需要编写两个不同的脚本,以防止主循环也崩溃。

bsearch finds the limit as fast as possible, without having to iterate over every single possiblity.

bsearch尽可能快地找到极限,而不必遍历每一种可能。

Code

many_ands.rb

# many_ands.rb
many_ands = (['true'] * (ARGV[0].to_i + 1)).join(' && ')
eval(many_ands)

max_ands.rb

big_number = 100_000

max_ands = (0..big_number).bsearch do |i|
  print "Testing #{i} : "
  result = system("ruby many_ands.rb #{i}")
  puts result ? 'Fine' : "Too many &&'s"
  puts
  !result
end

puts "Max number of &&'s without exception : #{max_ands - 1}"

It outputs:

输出:

Testing 50000 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 25000 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 12500 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 6250 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 3125 : Fine

Testing 4688 : Fine

Testing 5469 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5079 : Fine

Testing 5274 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5177 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5128 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5104 : Fine

Testing 5116 : Fine

Testing 5122 : Fine

Testing 5125 : Fine

Testing 5127 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Testing 5126 : many_ands.rb:2:in `eval': stack level too deep (SystemStackError)
    from many_ands.rb:2:in `<main>'
Too many &&'s

Max number of &&'s without exception : 5125

It depends on the system : On my Linux VM, it returned 5125. On a server, it returned 7930.

这取决于系统:在我的Linux VM上,它返回5125。在服务器上,它返回7930。

Results vary a bit from one run to the other, even on the same system.

结果在一次运行到另一次运行时有所不同,即使在相同的系统上也是如此。

eval or &&?

Where does the limitation come from? Is it from the string length passed to eval or does it come from the number of &&s?

限制从何而来?是从传递给eval的字符串长度,还是来自&&s的数量?

By modifying many_ands.rb, we now pass a big string to eval with many small expressions instead of one huge && expression:

通过修改many_ands。rb,我们现在传递一个大字符串,用许多小的表达式来计算,而不是一个大的&表达式:

many_ands = (['true'] * (ARGV[0].to_i + 1)).join(';')
eval(many_ands)

The main loop outputs:

主循环输出:

Testing 5000000 : Fine

Testing 7500000 : Fine

Testing 8750000 : Fine

Testing 9375000 : Fine

Testing 9687500 : Fine

Testing 9843750 : Fine

Testing 9921875 : Fine

Testing 9960938 : Fine

Testing 9980469 : Fine

Testing 9990235 : Fine

Testing 9995118 : Fine

Testing 9997559 : Fine

Testing 9998780 : Fine

Testing 9999390 : Fine

Testing 9999695 : Fine

Testing 9999848 : Fine

Testing 9999924 : Fine

Testing 9999962 : Fine

Testing 9999981 : Fine

Testing 9999991 : Fine

Testing 9999996 : Fine

Testing 9999998 : Fine

Testing 9999999 : Fine

Testing 10000000 : Fine

max_and.rb:11:in `<main>': undefined method `-' for nil:NilClass (NoMethodError)

It seems the limitation does come from the number of &&s in the expression. With 10 million true;..., the string passed to eval is 50MB big.

似乎限制来自于表达式中的&&s的数量。1000万真的,…,传递给eval的字符串是50MB大。

#2


4  

I realized that the if statement using 4 && works fine but when I start adding a fifth it will not.

我意识到使用4 &&的if语句是有效的,但是当我开始添加第五个时,它就不能了。

There is no limit to the number of && you use in a statement. So it will work with 4, 5, 100.

在语句中使用&& &的数量没有限制。它对4,5,100都成立。

It fails because some of the conditions are falsey.

它失败了,因为有些条件是不稳定的。

#3


3  

&& is a boolean operator. There is no theoretical limit as to how many if statements it can hold.

&是一个布尔运算符。对于它能容纳多少个if语句,没有理论上的限制。

Using lots in a single statement could be considered a code smell in Ruby, but there's no technical reason why you cannot do it.

在一个语句中使用lot可以被认为是Ruby中的代码味道,但是没有任何技术原因可以解释为什么不能这样做。

What error are you getting?

你犯了什么错误?