Can't convert String into Integer (TypeError)

Okay, I'm stumped. I've been looking at this program off-and-on for 3 days now and I can't understand why it's failing like it does. It's *supposed* to fail, but not the way it does.

The Image#dissolve method takes 2 arguments, an Image object and a percentage. The percentage argument can be specified either as a number between 0.0 and 1.0, or as a string in the form "NNN%", like "50%" for example. In this test I'm passing "1x0%" as the percentage, which is clearly incorrect. I expect dissolve to raise an ArgumentError exception with the message "expected percentage, got `1x0%'". What actually happens is that I get

/Users/timothyhunter/Temporary/bug.rb:22:in `raise': can't convert String into Integer (TypeError)
        from /Users/timothyhunter/Temporary/bug.rb:22:in `dissolve'
        from /Users/timothyhunter/Temporary/bug.rb:43

Line 22 is the "raise" statement.

What am I missing?

require 'RMagick'

module Magick
    class Image
               # Similar to `composite self -dissolve pct overlay'
        # Returns composited result
        def dissolve(overlay, pct)
            begin
                # Clamp to 0 <= pct <= 1
                pct = [1.0, Float(pct)].min
                pct = [0.0, pct].max
                # Convert to 0 <= pct <= 100
                pct = (pct * 100.0).to_i
            rescue
                m = pct.to_s.match(/\A(\d+)%\z/)
                if m
                    # Clamp to 0 <= pct <= 100
                    pct = [100, m[1].to_i].min
                    pct = [0, pct].max
                else raise ArgumentError, "expected percentage, got `#{pct}'"
                end
            end
                       temp = overlay.geometry
            begin
                overlay.geometry = pct.to_s
                res = composite(overlay, 0, 0, Magick::DissolveCompositeOp)
            ensure
                overlay.geometry = temp
            end
            return res
        end
           end
end

# composite Flower_Hat.jpg -dissolve 90 Violin.jpg
bgnd = Magick::Image.read('Flower_Hat.jpg').first
overlay = Magick::Image.read('Violin.jpg').first

bgnd.dissolve(overlay, '1x0%').display

jib:~ > ruby -r RMagick -e' p Magick::Image.instance_methods.grep(/raise/) '
   ["raise"]

btw, seems like you could get away with something like:

   pct = Float(pct) rescue (Float(pct.to_s.delete('%'))/100)
   r = 0.0 .. 1.0
   pct = [r.min, pct].max
   pct = [r.max, pct].min

cheers.

-a

···

On Thu, 3 Aug 2006, Timothy Hunter wrote:

Okay, I'm stumped. I've been looking at this program off-and-on for 3 days now and I can't understand why it's failing like it does. It's *supposed* to fail, but not the way it does.

The Image#dissolve method takes 2 arguments, an Image object and a percentage. The percentage argument can be specified either as a number between 0.0 and 1.0, or as a string in the form "NNN%", like "50%" for example. In this test I'm passing "1x0%" as the percentage, which is clearly incorrect. I expect dissolve to raise an ArgumentError exception with the message "expected percentage, got `1x0%'". What actually happens is that I get

/Users/timothyhunter/Temporary/bug.rb:22:in `raise': can't convert String into Integer (TypeError)
      from /Users/timothyhunter/Temporary/bug.rb:22:in `dissolve'
      from /Users/timothyhunter/Temporary/bug.rb:43

Line 22 is the "raise" statement.

What am I missing?

--
we can never obtain peace in the outer world until we make peace with
ourselves.
- h.h. the 14th dali lama

Arg! I should spend more time coding in Ruby and less in C. Thanks, Ara!

"1%0%".delete('%') => "10". Might be a bit too tolerent, don't you think?

I had the clamping down to 1 line but when I looked at it the next day I couldn't tell if it was correct or not :frowning:

···

ara.t.howard@noaa.gov wrote:

  jib:~ > ruby -r RMagick -e' p Magick::Image.instance_methods.grep(/raise/) '
  ["raise"]

btw, seems like you could get away with something like:

  pct = Float(pct) rescue (Float(pct.to_s.delete('%'))/100)
  r = 0.0 .. 1.0
  pct = [r.min, pct].max
  pct = [r.max, pct].min

cheers.

-a

BTW, another fun way to write the three last lines would be :

[0.0, pct, 1.0].sort[1]

But it doesn't convey the meaning well... :slight_smile:

Fred

···

Le 2 août 2006 à 23:38, ara.t.howard@noaa.gov a écrit :

btw, seems like you could get away with something like:

   pct = Float(pct) rescue (Float(pct.to_s.delete('%'))/100)
   r = 0.0 .. 1.0
   pct = [r.min, pct].max
   pct = [r.max, pct].min

--
I bought me an illusion An' I put it on the wall
I left it fill my head with dreams And I had to have them all
But oh the taste is never so sweet As what you'b believe it is...
Well I guess it never is (Guns n' Roses, Locomotive)

  jib:~ > ruby -r RMagick -e' p Magick::Image.instance_methods.grep(/raise/) '
  ["raise"]

btw, seems like you could get away with something like:

  pct = Float(pct) rescue (Float(pct.to_s.delete('%'))/100)
  r = 0.0 .. 1.0
  pct = [r.min, pct].max
  pct = [r.max, pct].min

cheers.

-a

Arg! I should spend more time coding in Ruby and less in C. Thanks, Ara!

yeah - i have the opposite issue :wink:

"1%0%".delete('%') => "10". Might be a bit too tolerent, don't you think?

dunno. you could do pct.sub(/%$/,'') too. lately i've found that parameter
checking just comes back to haunt me - though i do it heavily in certain
situations. just food for thought.

I had the clamping down to 1 line but when I looked at it the next day I couldn't tell if it was correct or not :frowning:

indeed - i tend even to avoid method chaining in production code for that
reason - it makes logs less than useful for pinpointng errors

cheers.

-a

···

On Thu, 3 Aug 2006, Timothy Hunter wrote:

ara.t.howard@noaa.gov wrote:

--
we can never obtain peace in the outer world until we make peace with
ourselves.
- h.h. the 14th dali lama