What’s the best way to write this program so that it will run correctly
on both 1.8 and 1.9? This works, but I’m just curious if there’s
anything better, preferably without the RUBY_VERSION test, without
adding methods to String, and without losing much efficiency compared
with 1.8’s String#[].
if RUBY_VERSION =~ /\A1.9/
def third_char_as_fixnum(s)
s[2].ord
end
else
def third_char_as_fixnum(s)
s[2]
end
end
s = “abc”
p third_char_as_fixnum(s) # ==> 99
Hi –
On Tue, 21 Jul 2009, Joel VanderWerf wrote:
else
def third_char_as_fixnum(s)
s[2]
end
end
s = “abc”
p third_char_as_fixnum(s) # ==> 99
I’m sure someone will have something more elegant but I’ll get the
ball rolling with:
def third_char_as_fixnum(s)
s[2,1].unpack(“C*”)[0]
end
It may not pass the not losing much efficiency test, though.
David
David A. Black wrote:
def third_char_as_fixnum(s)
s[2,1].unpack(“C*”)[0]
end
Hm, worth a try, and also:
s[2,1].unpack(“C”).first
Joel VanderWerf wrote:
David A. Black wrote:
def third_char_as_fixnum(s)
s[2,1].unpack(“C*”)[0]
end
About a factor of three slower, as I measure it:
require ‘benchmark’
if RUBY_VERSION =~ /\A1.9/
def third_char_as_fixnum_1(s)
s[2].ord
end
else
def third_char_as_fixnum_1(s)
s[2]
end
end
def third_char_as_fixnum_2(s)
s[2,1].unpack(“C”).first
end
s = “abc”
N = 1_000_000
Benchmark.bmbm(12) do |bm|
bm.report(“1”) {N.times {third_char_as_fixnum_1(s)}}
bm.report(“2”) {N.times {third_char_as_fixnum_2(s)}}
end
END
Rehearsal -----------------------------------------------
1 1.060000 0.000000 1.060000 ( 1.079800)
2 1.620000 0.000000 1.620000 ( 1.634525)
-------------------------------------- total: 2.680000sec
user system total real
1 0.580000 0.000000 0.580000 ( 0.598929)
2 1.640000 0.000000 1.640000 ( 1.664318)
At 2009-07-20 02:20PM, “Joel VanderWerf” wrote:
end
else
def third_char_as_fixnum(s)
s[2]
end
end
s = “abc”
p third_char_as_fixnum(s) # ==> 99
This works in both 1.9.1 and 1.8.7
def third_char_as_fixnum(s)
s[2].ord
end
Because Integer#ord returns the integer receiver.
[email protected] wrote:
ruby -v -rfoo -e ‘p “foo”[2].ord’
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-linux]
111
Still meets the constraint: “without adding methods to String”
That seems like a pretty good approach, actually, and it happens to be
what the snmp gem does (lib/ber.rb):
Add ord method to Fixnum for forward compatibility with Ruby 1.9
if “a”[0].kind_of? Fixnum
unless Fixnum.methods.include? :ord
class Fixnum
def ord; self; end
end
end
end
Joel VanderWerf wrote:
[email protected] wrote:
…
cat foo.rb
unless 0.respond_to?(:ord)
class Integer
def ord; self; end
end
end
…
Still meets the constraint: “without adding methods to String”
That seems like a pretty good approach, actually, and it happens to be
what the snmp gem does (lib/ber.rb):
The reason I wanted to avoid adding anything to String was that I
couldn’t think of a method name that would be pretty safe from conflict
without being too verbose or obscure (String#get_nth_char_as_int ?).
It’s hard to imagine Integer#ord ever meaning anything other than this
(it does in 1.8.7 and 1.9.1, as Glenn pointed out), so it seems safe to
import it from future, as they say.
Thanks everyone! (This will help bit-struct run in 1.9.)
Hi –
On Tue, 21 Jul 2009, Joel VanderWerf wrote:
end
Add ord method to Fixnum for forward compatibility with Ruby 1.9
if “a”[0].kind_of? Fixnum
unless Fixnum.methods.include? :ord
class Fixnum
def ord; self; end
end
end
end
There’s always a bit of fragility, since someone else might have added
an ord that does something else… unlikely, of course, but still.
Also, I didn’t suggest adding String#ord because you had said you
didn’t want to add methods to String (though your next post clarifies
what you meant by that). If you want to be more future-esque you could
add it to String instead of Fixnum (though that might involve one of
those unpack-based implementations and therefore not be as fast).
David
preferably without the RUBY_VERSION test, without adding methods to
String, and without losing much efficiency compared with 1.8’s String#[].
This may not be pretty, but you do not need to add anything.
It works on 1.8.6, 1.8.7, and 1.9.0 if byte is good enough.
s[2…2].each_byte{|f| p f}
Harry
On Mon, Jul 20, 2009 at 7:40 PM, Glenn J.[email protected] wrote:
s[2].ord
This works in both 1.9.1 and 1.8.7
def third_char_as_fixnum(s)
s[2].ord
end
Because Integer#ord returns the integer receiver.
ruby -v -e ‘p “foo”[2].ord’
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-linux]
-e:1: undefined method `ord’ for 111:Fixnum (NoMethodError)
cat foo.rb
unless 0.respond_to?(:ord)
class Integer
def ord; self; end
end
end
ruby -v -rfoo -e ‘p “foo”[2].ord’
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-linux]
111
Still meets the constraint: “without adding methods to String”