Hi, basically I need to implement a Hash in which keys can be encoded
with “pseudo” hexadecimal. This is basically to store URI parameters
and headers (defined in RFC 2396), so:
“tag” == “t%61g”
“alice” == “%61l%69ce”
I’m implementing a UriParametersHash using “Derivate” (thanks to Robert
Klemme):
require ‘delegate’
class UriParametersHash < DelegateClass(Hash)
CiString = Struct.new :string do
def unescape(string)
eval %{ "#{ string.gsub(/%/,'\x') }" }
end
private :unescape
def to_s
string.downcase
end
def hash
unescape(string.downcase).hash
end
def eql?(s)
unescape(string.downcase).eql? unescape(s.string.downcase)
end
alias == eql?
def inspect; string.inspect; end
end # CiString
def initialize
super({})
end
attr_accessor :modified
def []=(k,v)
k = CiString.new(k) if String === k
__getobj__[k] = v
end
def [](k)
k = CiString.new(k) if String === k
end
end # class UriParametersHash
It works ok:
@uri
=> {“a”=>123, “T%61g”=>“lalala”}
@uri[“tag”]
=> “lalala”
@uri[“T%61G”] = “lololo”
=> “lololo”
But I need to implement other Hash methods as “delete”, “find”,
“find_all”… and I get into problems: For example I define “find” in
this way:
def find()
k = CiString.new(k) if String === k
__getobj__"find" (k)
end
But it gives me an error:
@uri.find{|e| e[0]==“tag”}
ArgumentError: wrong number of arguments (1 for 0)
from uri.rb:100:in __getobj__' from uri.rb:100:in
find’
Unfortunatelly I don’t find good documentation to handle
__getobj__method, could somebody give me a tip please? Thanks a lot.
Iñaki Baz C.
[email protected]
Hi,
2008/5/23 Iñaki Baz C. [email protected]:
require 'delegate'
string.downcase
def []=(k,v)
=> “lololo”
__getobj__method, could somebody give me a tip please? Thanks a lot.
Here is a modified version including find and find_all:
require 'delegate'
class UriParametersHash < DelegateClass(Hash)
CiString = Struct.new :string do
def unescape(string)
eval %{ "#{ string.gsub(/%/,'\x') }" }
end
private :unescape
def to_s
string.downcase
end
def hash
unescape(string.downcase).hash
end
def eql?(s)
s = CiString.new(s) if String === s
unescape(string.downcase).eql?
unescape(s.string.downcase)
end
alias == eql?
def inspect; string.inspect; end
end # CiString
def initialize
super({})
end
attr_accessor :modified
def []=(k,v)
k = CiString.new(k) if String === k
__getobj__[k] = v
end
def [](k)
k = CiString.new(k) if String === k
__getobj__[k]
end
def find(ifnone = nil,&blk)
__getobj__.find(ifnone,&blk)
end
def find_all(&blk)
__getobj__.find_all(&blk)
end
end # class UriParametersHash
Regards,
Park H.
2008/5/23, Heesob P. [email protected]:
def find(ifnone = nil,&blk)
__getobj__.find(ifnone,&blk)
end
def find_all(&blk)
__getobj__.find_all(&blk)
end
Thanks a lot, but it gives me errors:
@uri
=> {“T%61g”=>“%61liCE”, “qwe”=>“qqqqqqqqqqQQQQQQQQQQQ”}
@uri.find {|e| e[0] == “qwe” }
NoMethodError: undefined method string' for "qwe":String from uri.rb:72:in
==’
from (irb):6
from (irb):6:in find' from uri.rb:98:in
each’
from uri.rb:98:in find' from uri.rb:98:in
find’
from (irb):6
Unfortunatelly I have no idea of how to debug it since I don’t
understand how exactly Delegator works. Any tip please?
Really thanks a lot.
Hi,
2008/5/23 Iñaki Baz C. [email protected]:
__getobj__[k]
from (irb):6:in `find'
from uri.rb:98:in `each'
from uri.rb:98:in `find'
from uri.rb:98:in `find'
from (irb):6
Unfortunatelly I have no idea of how to debug it since I don’t
understand how exactly Delegator works. Any tip please?
I guess you did not try my code.
I have modified eql? like this:
def eql?(s)
s = CiString.new(s) if String === s
unescape(string.downcase).eql? unescape(s.string.downcase)
end
Regards,
Park H.
2008/5/23, Heesob P. [email protected]:
Hi,
I guess you did not try my code.
I have modified eql? like this:
def eql?(s)
s = CiString.new(s) if String === s
unescape(string.downcase).eql? unescape(s.string.downcase)
end
Thanks both. I tryed the wrong code, I’ll try now what you suggest.
Thanks a lot.
On Fri, May 23, 2008 at 11:21 AM, Iñaki Baz C. [email protected] wrote:
__getobj__[k]
from (irb):6:in `find'
–
Iñaki Baz C.
[email protected]
I think you want something like:
def eql?(s)
unescape(string.downcase).eql? unescape(s.to_s.downcase)
end
with Park’s changes so that:
uri = UriParametersHash.new
uri[“T%61G”] = “lololo”
uri # => {“T%61G”=>“lololo”}
uri.find{|e| e[0] == “tag”} # => [“T%61G”, “lololo”]
Regards,
Sean