Can a TkVariable store a symbol?


#1

If I put a symbol into a TkVariable, it returns a string. The following
code
illustrates this:

require ‘tk’
a = TkVariable.new
a.value = :hi
puts a.value == :hi
puts a.value == “hi”

This results in

“false”
“true”

My question is, “Is this what’s supposed to happen, or is this a bug?”


#2

On Sun, 8 Apr 2007 04:18:59 +0900
Alex DeCaria removed_email_address@domain.invalid wrote:

This results in

“false”
“true”

My question is, “Is this what’s supposed to happen, or is this a bug?”

I think this is supposed to happen, as

:hi == ‘hi’

also returns false.

Wim


#3

Wim Vander S. wrote:

On Sun, 8 Apr 2007 04:18:59 +0900
Alex DeCaria removed_email_address@domain.invalid wrote:

This results in

“false”
“true”

My question is, “Is this what’s supposed to happen, or is this a bug?”

I think this is supposed to happen, as

:hi == ‘hi’

also returns false.

Wim

Wim,

Thanks for responding. The problem is that if you put a symbol into a
non-TkVariable, such as

b = :hi

then it stays as a symbol, and

b == :hi returns “true”, while b == “hi” is “false”.

But if b is a TkVariable, then the opposite occurs. This seems
inconsistent. I would expect that when I assign a symbol to a variable
that it won’t change to a string on me arbitrarilly. But, there may be
a good reason why it does this, and hopefully someone can explain why.

Alex


#4

On Apr 7, 2007, at 3:18 PM, Alex DeCaria wrote:

This results in

“false”
“true”

My question is, “Is this what’s supposed to happen, or is this a bug?”

It’s not a bug. A TkVariable object doesn’t maintain a @value
instance variable. So when you call TkVariable#value= and pass it a
symbol, the symbol will have to be coerced into something that the
underlying tcl/tk interpreter understands, which is a string. When
you call TkVariable#value, the string is retrieved from the tcl/tk
interpreter, but your TkVariable object has no memory of how the
value originated at this point.

To see how TkVariable handles different kinds of values, you can
evaluate code similar to the following:

require "tk" v = TkVariable.new(:foo) v.value # => "foo" v = TkVariable.new([1, 2, 3]) v.value # => "1 2 3" v = TkVariable.new(:foo => "red", :bar => "green") v.value # => {"foo"=>"red", "bar"=>"green"}

Note that hashes are handled specially. Personally, I have not
encountered a situation which needed a TkVariable object that was
built on a hash, but I’m sure such situations exist. Indeed, I would
be interested if someone would post something instructive about such
situations.

Regards, Morton


#5

Thanks Morton - That’s what I needed to know.

-Alex


#6

From: Alex DeCaria removed_email_address@domain.invalid
Subject: Re: Can a TkVariable store a symbol?
Date: Mon, 9 Apr 2007 08:26:33 +0900
Message-ID: removed_email_address@domain.invalid

Thanks Morton - That’s what I needed to know.

TkVariable can convert Tcl’s string to Ruby’s object automatically.
If you want to treat a Symbol on a TkVariable,
you can set ‘default_value_type’ of the TkVariable object.
For example,

$ irb
irb(main):001:0> require ‘tk’
=> true
irb(main):002:0> a = TkVariable.new
=> #<TkVariable: v00000>
irb(main):003:0> a.value = :hi
=> :hi
irb(main):004:0> a.value
=> “hi”
irb(main):005:0> a.symbol
=> :hi
irb(main):006:0> b = TkVariable.new(:hi, :symbol)
=> #<TkVariable: v00001>
irb(main):007:0> b.value
=> :hi
irb(main):008:0> b.string
=> “hi”
irb(main):009:0> a.default_value_type
=> nil
irb(main):010:0> b.default_value_type
=> :symbol
irb(main):011:0> a.numeric
ArgumentError: invalid value for Number: ‘hi’
from /usr/local/lib/ruby/1.8/tk/variable.rb:706:in number' from /usr/local/lib/ruby/1.8/tk/variable.rb:706:innumeric’
from (irb):20
from :0
irb(main):012:0> a.default_value_type = :symbol
=> :symbol
irb(main):013:0> a.value
=> :hi
irb(main):014:0> b.default_value_type = :string
=> :string
irb(main):015:0> b.value
=> “hi”
irb(main):016:0> a.value = 3
=> 3
irb(main):017:0> a.value
=> :“3”
irb(main):018:0> a.numeric
=> 3
irb(main):019:0> a.symbol
=> :“3”
irb(main):020:0> a.list
=> [“3”]
irb(main):021:0> a.numlist
=> [3]
irb(main):022:0> a.bool
=> true
irb(main):023:0> a.value = 1
=> 1
irb(main):024:0> a.bool
=> true
irb(main):025:0> a.value = 0
=> 0
irb(main):026:0> a.bool
=> false
irb(main):027:0> a.value = ‘yes’
=> “yes”
irb(main):028:0> a.bool
=> true
irb(main):029:0> a.value = ‘no’
=> “no”
irb(main):030:0> a.bool
=> false
irb(main):031:0> a.value = true
=> true
irb(main):032:0> a.bool
=> true
irb(main):033:0> a.value = false
=> false
irb(main):034:0> a.bool
=> false
irb(main):035:0> a.value
=> :“0”
irb(main):036:0> a.string
=> “0”
irb(main):037:0> a.value = true
=> true
irb(main):038:0> a.string
=> “1”
irb(main):039:0>

And, following operations are available too.


$ irb
irb(main):001:0> require ‘tk’
=> true
irb(main):002:0> a = TkVariable.new(1)
=> #<TkVariable: v00000>
irb(main):003:0> a.value
=> “1”
irb(main):004:0> a + 1
=> 2
irb(main):005:0> a.value
=> “1”
irb(main):006:0> a + ‘foo’
=> “1foo”
irb(main):007:0> a.value
=> “1”
irb(main):008:0> a.numeric += 2
=> 3
irb(main):009:0> a.value
=> “3”
irb(main):010:0> a.string += ‘zzz’
=> “3zzz”
irb(main):011:0> a.value
=> “3zzz”
irb(main):012:0>


#7

On Apr 8, 2007, at 7:26 PM, Alex DeCaria wrote:

Thanks Morton - That’s what I needed to know.

As you can see from the posting by NAGAI san, there is lot more to
TkVariable than what I had worked out. Most important, of course, is
that I wasn’t aware that one can have the behavior that you asked
for if by making use TkVariable#default_value_type=.

Regards, Morton


#8

On Apr 8, 2007, at 10:24 PM, Hidetoshi NAGAI wrote:


=> :hi
irb(main):011:0> a.numeric
=> :string
irb(main):020:0> a.list
=> 0
irb(main):031:0> a.value = true
=> “0”
$ irb
irb(main):006:0> a + ‘foo’
=> “3zzz”
irb(main):012:0>

Thank you for posting this. I learned several new things about the
capabilities of TkVariable from it.

Regards, Morton