Variable names

About a year ago, I wrote a simple type enforcement library that adds a
should_be method to the Object class. This method looks like this:

def should_be(types, varName)
# types is either a Class or an array of Classes
# that are legal types (or super-types, if you will)
# for self

# varName is the symbol for the variable; we use this
 # when we throw the exception

<type checking code>

# we throw an exception if self is not of one of
 # the types specified

end

So, say we have a method print_line that takes two parameters (1) an
integer line number and (2) a string which is the line.

def print_line(lineNo, line)
lineNo.should_be(Integer, :lineNo)
line.should_be(String, :line)
# by now, we would have thrown a TypeError if lineNo
# and line are not an Integer and a String respectively

<code to make this method live up to its name>

end

We’ve been using this for a year now. Several months ago I rewrote it
so that it is in C so that it doesn’t appreciably increase overhead.
The good news is that it works quite well and completely fulfills our
type checking needs.

The issue is that I don’t like having to pass the symbol for the
variable, because it strikes me as inelegant. Right now, I only pass
the symbol so that I can construct an error message saying (for
example) “variable ‘loginIDs’ is of the wrong type ‘Integer’; expected
’Array’”. I feel that it would be much cleaner to simply say
loginIDs.should_be(Integer). I may be quite dense and perhaps I am
missing something obvious, but I have combed through the source code
for 1.6.x and 1.8.1 and I haven’t been able to find anything (I’ve
tried every conceivable combination of ‘object id’ and 'name for id’
functions, but of course these are two entirely different kinds of
ids).

Thus my question:

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

Thanks,

Dave

···

David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request

You have the file name and line number, and you may even have the file
itself in SCRIPT_LINES, so you could cheat and find the name from that.

I’m interested in tis experiment: how often does it catch a problem
that you didn’t catch though unit testing? Putting that another way:
how often do you see these type errors in testing, and how often in
production?

Cheers

Dave

···

On Apr 2, 2004, at 10:20, David King Landrith wrote:

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it 'x'?

Well, with this

  a = b = 12

which is the name associated with the object 12 ?

Guy Decoux

[snip]

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

Thanks,

You want something like this ?

ruby a.rb
a.rb:4:in should_be': expected String, but got Fixnum (TypeError) from a.rb:12:in test’
from a.rb:16
expand -t2 a.rb
class Object
def should_be(klass)
unless self.kind_of?(klass)
raise TypeError, <<-MSG.gsub(/^\s*/, ‘’)
expected #{klass}, but got #{self.class}
MSG
end
end
end
def test(str)
str.should_be(String)
end
test(“hello”)
test(666) # boom… as we expect

···

On Sat, 03 Apr 2004 02:20:24 +0900, David King Landrith wrote:


Simon Strandgaard

Since what you want doesn’t (to me) intuitively exist, I suggest
rewriting it as:

def print_line(lineNo, line)
should_be(Integer, :lineNo)
should_be(String, :line)

def evaluate_local_variable(var)
if local_variables.include? var
eval var
else
raise ArgumentError, “You didn’t give me a local variable: #{var}”
end
end

You can probably improve on that, and write it in C, but you get the
idea.

Cheers,
Gavin

···

On Saturday, April 3, 2004, 2:20:24 AM, David wrote:

So, say we have a method print_line that takes two parameters (1) an
integer line number and (2) a string which is the line.

def print_line(lineNo, line)
lineNo.should_be(Integer, :lineNo)
line.should_be(String, :line)
# by now, we would have thrown a TypeError if lineNo
# and line are not an Integer and a String respectively
[…]

From what I understand, since 12 is a FixNum, a and b end up being
separate FixNum objects with their own separate values of 12. But this
strikes me as beside the point.

In the C api, each function gets passed a pointer to the struct which
represents self. You can pass this pointer to any number of functions
to get information about self; e.g., class along with variables and
their contents. So that for the FixNum ‘a’ above, we could discern
that it was a FixNum. The question is: Is there a method that wil tell
me that it is called ‘a’. If ‘self’ end up being a literal, then I
suppose its name is its value, but it seems to me that this would
simply be a question of how the interpreter works vis a vis its symbols
table.

···

On Apr 2, 2004, at 11:31 AM, ts wrote:

Is there any way to access the name of a given variable instance
from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

Well, with this

a = b = 12

which is the name associated with the object 12 ?


David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

You have the file name and line number, and you may even have the file
itself in SCRIPT_LINES, so you could cheat and find the name from
that.

I’m looking for something more general. We don’t actually have such a
print_line method, I simply made it up for the email since it was a
good example.

I’m interested in tis experiment: how often does it catch a problem
that you didn’t catch though unit testing? Putting that another way:
how often do you see these type errors in testing, and how often in
production?

Often enough to justify it, given the complexity of our application.
We’ve written a Ruby api upon which our program is based, and it has
about than 18,000 lines (25k ruby, 3k in C). Our program (or group of
programs surrounding the application) totals least 25,000 lines. As a
consequence, we have tons of unforeseen contingencies and type checking
provides an important way to eliminate one class of these.

Since most of our application touches a SQL database in some way (we’ve
rolled our own ruby database API in C to handle persistence layers and
eliminate the overhead endemic to the dbd/dbi arrangement, since our
tables have 10s of millions of records and we’re pushing and pulling
gigabytes of data) destructive errors are a real possibility; E.g., we
don’t want to insert #Module::Object:0x40536218 into a varchar field.
And since we often have a method calling a method calling a method and
so on, without type checking it can be quite difficult to locate where
our string got swapped for something else. Also, given the complexity
of the program, the behavior that elicits the swap may very well be
latent in very, very well tested code. Does this make sense?

···

On Apr 2, 2004, at 11:30 AM, Dave Thomas wrote:

On Apr 2, 2004, at 10:20, David King Landrith wrote:


David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request

This looks like a restricted version of Eivind Eklund’s types.rb. Here’s
what the author had to say about it:

“The reason I didn’t do any particularly public release of it was
that I found that adding type checks to ruby programs were worse
than useless for me - it got in the way of my refactoring, without
catching many bugs.”

See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/84841.

···

On Sat, Apr 03, 2004 at 01:30:34AM +0900, Dave Thomas wrote:

On Apr 2, 2004, at 10:20, David King Landrith wrote:

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

You have the file name and line number, and you may even have the file
itself in SCRIPT_LINES, so you could cheat and find the name from that.

I’m interested in tis experiment: how often does it catch a problem
that you didn’t catch though unit testing? Putting that another way:
how often do you see these type errors in testing, and how often in
production?


Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

“You, sir, are nothing but a pathetically lame salesdroid!
I fart in your general direction!”
– Randseed on #Linux

I think this is what ts is pointing out:

set a, b and c; set a’s @foo instance variable to 42

a = b = 23 #=> 23
a.instance_eval{@foo=42} #=> 42
c = 23 #=> 23

show everyone’s @foo

[ a.instance_eval{@foo},
b.instance_eval{@foo},
c.instance_eval{@foo},
23.instance_eval{@foo}] #=> [42, 42, 42, 42]

show everyone’s id

[a.id, b.id, c.id, 23.id] #=> [47, 47, 47, 47]

All instances of 23 are exactly the same object. No difference
whatsoever. the variable name is like a nickname (thanks Why :), it’s
just one of many pointers to the object. I really don’t think that
there is any way to get the name assigned to that pointer, especially
since the number of names assigned to that one object can be anywhere
from 0 to infinity :slight_smile: (well, infinite for practical purposes anyway…)

I looked around though, at Symbols.all_symbols,
ObjectSpace.each_object, and I couldn’t find any way to tie them
together… perhaps there is a way, but I’m not sure that you will be
getting the right symbol for the context you are in even if you do…

–Mark

···

On Apr 2, 2004, at 11:43 AM, David King Landrith wrote:

On Apr 2, 2004, at 11:31 AM, ts wrote:

Is there any way to access the name of a given variable instance
from
within it? In other words, for any object x, is there C function
to
which I can pass self to determine that the program calls it ‘x’?

Well, with this

a = b = 12

which is the name associated with the object 12 ?

From what I understand, since 12 is a FixNum, a and b end up being
separate FixNum objects with their own separate values of 12. But
this strikes me as beside the point.

From what I understand, since 12 is a FixNum, a and b end up being
separate FixNum objects with their own separate values of 12. But this
strikes me as beside the point.

This is incorrect. a and b would both point to the same FixNum object.
In fact, I wouldn’t be surprised if all direct references to 12 were the same
FixNum object for efficiency purposes.

In the C api, each function gets passed a pointer to the struct which
represents self. You can pass this pointer to any number of functions
to get information about self; e.g., class along with variables and
their contents. So that for the FixNum ‘a’ above, we could discern
that it was a FixNum. The question is: Is there a method that wil tell
me that it is called ‘a’. If ‘self’ end up being a literal, then I
suppose its name is its value, but it seems to me that this would
simply be a question of how the interpreter works vis a vis its symbols
table.

The name of the variable that points to the object isn’t an inherent part
of the object, though. Like above, you can have any number of variables
representing the same object. Also, you could have many objects referencing
that same object (for example, if it’s stored in an array). Should an object
also keep references to all objects that reference it?

Variable names are incidental. For example:

def foo
a = String.new
end

x = foo

When inside the method foo, the string is pointed to by the local variable a.
However, outside, it’s pointed to by the local variable x. What has changed
about the object? Nothing.

Variables are a lot like pointers in C. You allocate a pointer to store the
address of some other memory. It doesn’t make sense for every piece of
memory to also store the addresses of all pointers that point to it.

  • Dan
···

On Friday 02 April 2004 2:43 pm, David King Landrith wrote:

I looked at this before we rolled our own, and decided against using it
because it seemed overkill. We just add xxx.should_be(type, symbol) or
yyy.should_be([type1, type1…], symbol) whenever we want to ensure
failure due to type mixups. We make no attempt in our library to try
to dictate particular combinations parameters, because this seems to me
to go beyond the point of diminishing returns. We haven’t found that
it impacts refactoring in the least bit. Since we are dealing with a
very large code base, this helps us in two ways:

  1. It often keeps harmful things from happening; e.g.,
    #Module::Object:0x40536218 being inserted into a varchar field
  2. In many cases, some error would have occurred as the result of the
    wrong type being sent, but forcing it to be an explicit type error
    ensures that (a) the error report accurately reflects the problem, and
    (b) the error is thrown closer to where it occurred.

Best,

Dave

···

On Apr 2, 2004, at 4:28 PM, Mauricio Fernández wrote:

On Sat, Apr 03, 2004 at 01:30:34AM +0900, Dave Thomas wrote:

On Apr 2, 2004, at 10:20, David King Landrith wrote:

Is there any way to access the name of a given variable instance from
within it? In other words, for any object x, is there C function to
which I can pass self to determine that the program calls it ‘x’?

You have the file name and line number, and you may even have the file
itself in SCRIPT_LINES, so you could cheat and find the name from
that.

I’m interested in tis experiment: how often does it catch a problem
that you didn’t catch though unit testing? Putting that another way:
how often do you see these type errors in testing, and how often in
production?

This looks like a restricted version of Eivind Eklund’s types.rb.
Here’s
what the author had to say about it:

“The reason I didn’t do any particularly public release of it was
that I found that adding type checks to ruby programs were worse
than useless for me - it got in the way of my refactoring, without
catching many bugs.”

See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/84841.


David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request

would’nt a proper test-only database fit the need better than type
checking ?

(note that I’d like Soft Typing a-la Jscript.net in ruby, I’m just
looking for some good proof of the need for it :slight_smile:

Btw, have you listed this cool big ruby-based project on the
RealWorldRuby wiki page? :slight_smile:

···

il Sat, 3 Apr 2004 04:43:58 +0900, David King Landrith dlandrith@mac.com ha scritto::

Since most of our application touches a SQL database in some way (we’ve
rolled our own ruby database API in C to handle persistence layers and
eliminate the overhead endemic to the dbd/dbi arrangement, since our
tables have 10s of millions of records and we’re pushing and pulling
gigabytes of data) destructive errors are a real possibility;

From what I understand, since 12 is a FixNum, a and b end up being
separate FixNum objects with their own separate values of 12. But this
strikes me as beside the point.

You have not understood my example. Suppose that you want to define a
method #name, give me the result for this

   def tt(x, y)
      p x.name, y.name
   end

   a =
   tt(a, a)

my example has nothing to do with Fixnum

In the C api, each function gets passed a pointer to the struct which
represents self.

well, I think that I know a little the C API ...

Guy Decoux

Let me restate the question:

Whenever a method is called on an object, one and only one symbol is
used to represent the object. Is there any way to determine which
symbol was representing the object at the time that the method was
invoked?

Everything that has been said thus far leads me to believe that the
answer is no, but nobody has hit the point square on. I’m anxious to
clarify my question or provide more information if my question remains
unclear. But (as usual – and this is the reason I rarely use this
list) people seem more interested in pedantry than genuine assistance.
Don’t get me wrong, the answers are informative and often fill me with
awe at vast expanses of knowledge possessed by those that offer them.
They just provide both too much and not enough information at the same
time, which typically indicates that you’re dealing with either an
obscurantist (e.g., a politician) or a pedant.

···

On Apr 2, 2004, at 3:51 PM, Dan Doel wrote:

The name of the variable that points to the object isn’t an inherent
part
of the object, though. Like above, you can have any number of
variables
representing the same object. Also, you could have many objects
referencing
that same object (for example, if it’s stored in an array). Should an
object
also keep references to all objects that reference it?

Variable names are incidental. For example:

def foo
a = String.new
end

x = foo

When inside the method foo, the string is pointed to by the local
variable a.
However, outside, it’s pointed to by the local variable x. What has
changed
about the object? Nothing.

Variables are a lot like pointers in C. You allocate a pointer to
store the
address of some other memory. It doesn’t make sense for every piece of
memory to also store the addresses of all pointers that point to it.

  • Dan

David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

One useless man is a disgrace, two
are called a law firm, and three or more
become a congress – John Adams

public key available upon request


David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request

Not always:

(1 + 2).abs

Cheers

Dave

···

On Apr 2, 2004, at 15:35, David King Landrith wrote:

Let me restate the question:

Whenever a method is called on an object, one and only one symbol is
used to represent the object. Is there any way to determine which
symbol was representing the object at the time that the method was
invoked?

David King Landrith said:

Let me restate the question:

Whenever a method is called on an object, one and only one symbol is
used to represent the object.

That statement is incorrect.

Is there any way to determine which
symbol was representing the object at the time that the method was
invoked?

Simple answer: NO

Longer answer: Throw an exception and immediately catch it. Ask the
exception for its backtrace and parse the file and line number from the
backtrace (see ri backtrace for details). Then read the file in question
and find the line number of the caller function. Then parse the line of
code and guess at the variable name (if there is one).

If you always call your type checking method in the form

var.should_be(ClassName) # or whatever format you use

then parsing the line of code is not a difficult problem. However, in the
general case it is quite difficult.

···


– Jim Weirich jim@weirichhouse.org http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

David King Landrith wrote:

But (as usual – and this is the reason I rarely use this
list) people seem more interested in pedantry than genuine assistance.
Don’t get me wrong, the answers are informative and often fill me with
awe at vast expanses of knowledge possessed by those that offer them.
They just provide both too much and not enough information at the same
time, which typically indicates that you’re dealing with either an
obscurantist (e.g., a politician) or a pedant.

Or that somebody just isn’t interested in talking about what you asked,
either because they don’t know or just don’t want to talk about this.

That might sound rude, but think about the nature of this mailing list:
You’re not talking to one single person, but many persons. If somebody
replies to your thread another person might reply to that person
instead of you.

This will of course create responses which don’t interest the original
poster at all, but it will create responses which might interest other
persons in the group.

So all this is just natural – don’t be amazed or offended by it,
because obviously not every posting in your thread is directed at you.

Regards,
Florian Gross

I wasn’t trying to be pedantic.

I was trying to explain why you couldn’t do what you want to do,
as are other posts here (including the examples of Mr. Thomas
and Mr. Decoux, who each know far more about Ruby than both of
us put together I’m sure :)).

If all you want is a yes/no answer, I’m sure people here can
accomodate you, but I personally would rather know why I can’t
do something rather than simply knowing I can’t.

  • Dan

“Where can I find this fish’s bicycle?”

“Fish don’t have bicycles.”

“But they must have something like it. Can I find their cars?”

“No, they don’t have cars.”

“But they have to get to work somehow!”

“They do?”

“You guys are so unhelpful. I still don’t know where I can find the
bicycles.”

Charles Miller

···

On 03/04/2004, at 7:35 AM, David King Landrith wrote:

Whenever a method is called on an object, one and only one symbol is
used to represent the object. Is there any way to determine which
symbol was representing the object at the time that the method was
invoked?

Everything that has been said thus far leads me to believe that the
answer is no, but nobody has hit the point square on. I’m anxious to
clarify my question or provide more information if my question remains
unclear. But (as usual – and this is the reason I rarely use this
list) people seem more interested in pedantry than genuine assistance.
Don’t get me wrong, the answers are informative and often fill me
with awe at vast expanses of knowledge possessed by those that offer
them. They just provide both too much and not enough information at
the same time, which typically indicates that you’re dealing with
either an obscurantist (e.g., a politician) or a pedant.


Charles Miller charles@atlassian.com

Confluence: Thought-Sharing For Your Team

Replies like this make this list next to useless.

···

On Apr 2, 2004, at 4:46 PM, Dave Thomas wrote:

On Apr 2, 2004, at 15:35, David King Landrith wrote:

Let me restate the question:

Whenever a method is called on an object, one and only one symbol is
used to represent the object. Is there any way to determine which
symbol was representing the object at the time that the method was
invoked?

Not always:

(1 + 2).abs

Cheers

Dave


David King Landrith
(w) 617.227.4469x213
(h) 617.696.7133

Life is tough. It’s even tougher if you’re
an idiot. --John Wayne

public key available upon request