Can a TkVariable store a symbol?

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?"

···

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

I think this is supposed to happen, as

:hi == 'hi'

also returns false.

Wim

···

On Sun, 8 Apr 2007 04:18:59 +0900 Alex DeCaria <alex.decaria@millersville.edu> wrote:

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?"

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:

<code>
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"}
</code>

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

···

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

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?"

Wim Vander Schelden 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

···

On Sun, 8 Apr 2007 04:18:59 +0900 > Alex DeCaria <alex.decaria@millersville.edu> wrote:

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

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

-Alex

···

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

Message-ID: <dd2b9ec33344b0790a73d090f4b02785@ruby-forum.com>

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,

···

From: Alex DeCaria <alex.decaria@millersville.edu>
Subject: Re: Can a TkVariable store a symbol?
Date: Mon, 9 Apr 2007 08:26:33 +0900
-------------------------------------------------------------
$ 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:in `numeric'
        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>
-------------------------------------------------------------
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)

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

···

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

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

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

Regards, Morton

···

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

From: Alex DeCaria <alex.decaria@millersville.edu>
Subject: Re: Can a TkVariable store a symbol?
Date: Mon, 9 Apr 2007 08:26:33 +0900
Message-ID: <dd2b9ec33344b0790a73d090f4b02785@ruby-forum.com>

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:in `numeric'
        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>
-------------------------------------------------------------