Ruby / php operator differences

I am trying to do some parsing of binary data.

Here is the psuedo code that parses what i'm looking for:
private int readInteger() throws IOException {
    int n = 0;
    int b = in.readUnsignedByte();
    int result = 0;

    while ((b & 0x80) != 0 && n < 3) {
        result <<= 7;
        result |= (b & 0x7f);
        b = in.readUnsignedByte();
        n++;
    }
    if (n < 3) {
        result <<= 7;
        result |= b;
    } else {
      /* Use all 8 bits from the 4th byte */
      result <<= 8;
      result |= b;

      /* Check if the integer should be negative */
      if ((result & 0x10000000) != 0) {
        /* and extend the sign bit */
        result |= 0xe0000000;
      }
    }

    return result;
}

Here is how I wrote it with Ruby:
def read_int
    n = 0;
    b = @input_stream.read_special(1,'C')
    result = 0

    while((b & 0x80) != 0 && n < 3)
        result <<= 7
        result |= (b & 0x7f)
        b = @input_stream.read_special(1,'C')
        n = n + 1
    end
    if (n < 3)
        result <<= 7
        result |= b
    else
      # Use all 8 bits from the 4th byte
      result <<= 8
      result |= b

      #Check if the integer should be negative
      if ((result & 0x10000000) != 0)
        # and extend the sign bit
        result |= 0xe0000000
      end
    end

    STDOUT.puts "READ INT: #{result}"
    return result
  end

When translating the Pseudo Code to PHP, it's verbatim except for
syntax. With ruby, I think i've found the problem with it not parsing
correclty. the |= operator. With PHP

$i |= 0xe0000000; //= -536870912

Now with Ruby:
i |= 0xe000000 #= true

Any ideas on a solution?

thanks.

···

--
Posted via http://www.ruby-forum.com/.

Errm, how about providing some evidence for that claim?

irb(main):010:0> 5 | 3
=> 7
irb(main):011:0> i = 0
=> 0
irb(main):012:0> i |= 0xe000000
=> 234881024

···

On Thu, Mar 08, 2007 at 01:36:38PM +0900, Aaron Smith wrote:

When translating the Pseudo Code to PHP, it's verbatim except for
syntax. With ruby, I think i've found the problem with it not parsing
correclty. the |= operator. With PHP

$i |= 0xe0000000; //= -536870912

Now with Ruby:
i |= 0xe000000 #= true

Hi,

···

In message "Re: ruby / php operator differences." on Thu, 8 Mar 2007 16:07:18 +0900, Brian Candler <B.Candler@pobox.com> writes:

$i |= 0xe0000000; //= -536870912

Now with Ruby:
i |= 0xe000000 #= true

Errm, how about providing some evidence for that claim?

Maybe he assumed integers to be wrapped around 32bits?

              matz.

i wasn't 'claiming' anything. I was asking about why that was happening.
I figured it out though.

···

--
Posted via http://www.ruby-forum.com/.

Hi,

···

In message "Re: ruby / php operator differences." on Thu, 8 Mar 2007 16:11:52 +0900, Aaron Smith <beingthexemplary@gmail.com> writes:

i wasn't 'claiming' anything. I was asking about why that was happening.
I figured it out though.

Why that was happening? Could you tell me what you have figured out?

              matz.

Hey Matz

I ended up writing the method a bit different,

    int = @input_stream.read_special(1,'C')

    if(int < 128)
      STDOUT.puts "READ INT: #{int}"
      return int
    else
      int = (int & 0x7f) << 7
      tmp = @input_stream.read_special(1,'C')
      if(tmp < 128)
        STDOUT.puts "READ INT: #{int}"
        return int | tmp
      else
        int = (int | (tmp & 0x7f)) << 7
        tmp = @input_stream.read_special(1,'C')
        if(tmp < 128)
          STDOUT.puts "READ INT: #{int}"
          return int | tmp
        else
          int = (int | (tmp & 0x7f)) << 8
          tmp = @input_stream.read_special(1,'C')
          int |= tmp

          #Check if the integer should be negative
          if ((int & 0x10000000) != 0)
            ## and extend the sign bit
            int |= 0xe0000000
          end
          STDOUT.puts "READ INT: #{int}"
          int
        end
      end
    end

this seems to be working fine.

···

--
Posted via http://www.ruby-forum.com/.

would it make sense that in php:
$int |= 0x10000000
is just shorthand for
$int = $int | 0x10000000

···

--
Posted via http://www.ruby-forum.com/.

It's the same in Ruby, except it goes further:

int |= 0x10000000

is short for

int = int | 0x10000000

is short for

int = int.|(0x10000000) # infix operator is really method call on LHS

is short for

int = int.send(:|, 0x10000000) # explicit method call by symbolic name

···

On Fri, Mar 09, 2007 at 07:36:55AM +0900, Aaron Smith wrote:

would it make sense that in php:
$int |= 0x10000000
is just shorthand for
$int = $int | 0x10000000

It's the same in Ruby, except it goes further:

int |= 0x10000000

is short for

int = int | 0x10000000

is short for

int = int.|(0x10000000) # infix operator is really method call on
LHS

is short for

int = int.send(:|, 0x10000000) # explicit method call by symbolic name

pretty flippin cool.

in this example:
int = int.send(:|,0x1000000)

is it neccessary to have assignment portion? as in:
int.send(:|,0x1000000), does this take out the need for (int=)

···

--
Posted via http://www.ruby-forum.com/\.

You don't need to make use of the return value. Every expression in Ruby
returns a value, but you can simply ignore it.

In your particular example, if you write

int = 4
int.send(:|, 0x10000000)

it's valid Ruby but isn't very useful, as it calculates a result and then
throws it away. But many methods do have side effects:

str = "hello"
str.send(:concat, " world")
puts str

Actually you'd normally write the middle line as

str.concat(" world")

or

str.concat " world"

or

str << " world"

(since the << infix operator expands to a << method call on str, and for
Strings the << method does the same as concat)

This stems from the fact that a String in Ruby is a mutable object (it can
change). Most objects are. However a few objects, in particular numbers and
symbols, are immutable. That is, you can't send a message to the number 5
telling it to change its value :slight_smile:

Regards,

Brian.

···

On Sat, Mar 10, 2007 at 01:55:19PM +0900, Aaron Smith wrote:

> It's the same in Ruby, except it goes further:
>
> int |= 0x10000000
>
> is short for
>
> int = int | 0x10000000
>
> is short for
>
> int = int.|(0x10000000) # infix operator is really method call on
> LHS
>
> is short for
>
> int = int.send(:|, 0x10000000) # explicit method call by symbolic name

pretty flippin cool.

in this example:
int = int.send(:|,0x1000000)

is it neccessary to have assignment portion? as in:
int.send(:|,0x1000000), does this take out the need for (int=)

Brian Candler wrote:

···

On Sat, Mar 10, 2007 at 01:55:19PM +0900, Aaron Smith wrote:

> int = int.|(0x10000000) # infix operator is really method call on

is it neccessary to have assignment portion? as in:
int.send(:|,0x1000000), does this take out the need for (int=)

.................

Ah, yes that makes sense. Thanks.

--
Posted via http://www.ruby-forum.com/\.