Undefine

Well, you say you want it to no longer exist because you want it to no
longer exist. I'm not sure I see why, though I might not be reading
closely enough.

What about the logic of your code or design depends on the 'existence'
of a variable? What problem is it you're trying to solve with this
approach?

···

On Tue, 15 Jun 2004 05:22:40 +0900, tony summerfelt <snowzone5@hotmail.com> wrote:

On Tue, 15 Jun 2004 03:37:45 +0900, you wrote:

>> i just need the variable to 'not exist' however it's thought about (by
>> me or others :slight_smile: isn't a concern.

>Why is this?

i refer to my earlier message about a blackbox approach...

I did not advocate removing, a.k.a. undefining,
instance variable,

it would be a local variable i'd be undefining, probably not an
instance variable (although i'd like that option also)

for global variables, and removal method for local
variables make no sense at all.

only if the logic you use makes the code smaller or more efficient...

larry wall added it to perl for a reason, and i'm guessing that he
thought it would be handy :slight_smile:

how to use such an undefine action in a clean way
is something I have yet to figure out :wink:

i guess the code posted didn't do it for you? :slight_smile:

i wrote a nodelist processor for fidonet's nodelist, where i also used
defined/undef. it's quick and dirty way to make sure you're working
with valid data...

BTW: defined?() tells you about whether a variable
is defined, including local ones.

unfortunatley it doesn't do me any good, as i'll want to undef it
later.

···

On Tue, 15 Jun 2004 14:55:05 +0900, you wrote:

just makes the code shorter. here's an excerpt of a log trimming
program in perl (for the format that binkd generates) ('@' precedes
arrays in perl):

while(<binkd>)
{
    # date parsing code was here
     @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
     print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);
     next if defined(@diff);
     print $trimmed $_ if ! /(\[\d+\])/;
     undef(@diff);
}

this goes through each line in the log file.
if the log line contains a date stamp, it's processed and written to
an archive file if it meets the criteria, and the next line in the
file is read.

some lines are blank but i want written to the archive file for
cosmetic purposes. i COULD rewrite the perl code to NOT use
defined/undef (tim toadie and all that). but i don't have to.

when i ported it to ruby i found the equivalent ruby code longer.
maybe when i know the language a lot better it won't be and i'll find
a shorter way of doing it...

···

On Tue, 15 Jun 2004 05:31:30 +0900, you wrote:

What about the logic of your code or design depends on the 'existence'
of a variable? What problem is it you're trying to solve with this
approach?

tony summerfelt <snowzone5@hotmail.com> writes:

unfortunatley it doesn't do me any good, as i'll want to undef
it later.

Yes, but I think you may have missed something which (I think)
was mentioned earlier -- ruby automatically "defines" local
variables when they are parsed. Try it in irb:

irb(main):001:0> p a
NameError: undefined local variable or method `a' for main:Object
        from (irb):1
irb(main):002:0> a = 1 if false
=> nil
irb(main):003:0> p a
nil
=> nil
irb(main):004:0> p a.id
4
=> nil

So, using defined? in the way you used it in perl is really not
going to help you... Even though the "a = 1" was not evaluated,
a still becomes a local variable, bound to nil.

···

--
Josh Huber

I did not advocate removing, a.k.a. undefining,
instance variable,

it would be a local variable i'd be undefining, probably not an
instance variable (although i'd like that option also)

I think the whole point here is that it isn't Ruby-ish to rely on a variable being defined or not. Ruby wassn't built to do things in that way; a couple examples in this thread show how variables are automagically defined when code is parsed. They aren't defined at runtime, they are defined at eval time. So basically, If you are translating code from Perl that undefines local variables, you will have to find a different way of doing it, due to the way Ruby was designed. I doubt that this is likely to change, because it's part of how Ruby was designed.

If you know Ruby well, there is almost certainly a way to do it that is just as reasonable and sensical as the Perl way, but it would be sensical for Ruby.

for global variables, and removal method for local
variables make no sense at all.

only if the logic you use makes the code smaller or more efficient...

larry wall added it to perl for a reason, and i'm guessing that he
thought it would be handy :slight_smile:

It is very handy for Perl, I know :slight_smile: I used to use it. But there are other ways of doing the same sort of thing. To translate the given code into Ruby, I would (assuming that Delta_DHMS() won't return nil) write 'next unless diff.nil?', then later, 'diff = nil'. If there's a chance that the method might return nil, you can always use the trick Sean posted elsewhere on this thread.

···

On Jun 15, 2004, at 10:19 AM, tony summerfelt wrote:

On Tue, 15 Jun 2004 14:55:05 +0900, you wrote:

it would be a local variable i'd be undefining, probably not an
instance variable (although i'd like that option also)

In your code you used global variables, and they work different
in Perl than you seem to think. If you use a global variable
the Perl interpreter reserves an entry in the stash of the
package of the global variable. If you do "undef $a" you do
the equivalent of "$a = undef". This example shows, that
the entry exists even without assigning a value to the variable
$a:

perl -MData::Dumper -e 'sub d { print Dumper [ map { $_, ${"$_"} }\
  grep { /^a$/ } keys %{*{main::}} ] }; d(); $a; d(); '

If you use @a as a global variable it's no different, in fact
the same entry is used, but you can save different things to this entry
at the same time: scalars (those can be references or blessed
references, too), globs, code objects, arrays and hashes. (Thanks
for reminding me how horrible Perl's internals are, ugh!)

If you call defined on @a, what you actually do is checking if the
array @a contains any elements, because the stash entry exists in any
case. To use defined for aggregates is deprecated, see
perldoc -f defined:

: Use of "defined" on aggregates (hashes and arrays) is depre- cated.
: It used to report whether memory for that aggregate has ever been
: allocated. This behavior may disappear in future versions of Perl.
: You should instead use a simple test for size:
:
: if (@an_array) { print "has array elements\n" }
: if (%a_hash) { print "has hash members\n" }

Ruby's global variables work the same way as Perl's do. But if
you use lexical variables (starting with downcased letters),
the variables is !defined? until the interpreter sees an
assignment to it. It's BTW not necessary to execute the
assignment:

ruby -e 'p defined?(a); false and a = nil ; p defined?(a)'

If you use lexical variables in Perl you have to use "my $a", to reserve
memory for it in the current scope. In Perl it's of course not possible
to have a lexical variable that is undefined in the Ruby way, that is,
undefined before the "my $a", because it would be interpreted by Perl as
a global variable. This would lead to an entry for it in the stash like
shown above.

>>for global variables, and removal method for local
>>variables make no sense at all.
only if the logic you use makes the code smaller or more efficient...

Premature optimization is the root of all evil...

[defined?]

unfortunatley it doesn't do me any good, as i'll want to undef it
later.

So you can do "a = nil" or "$a = nil" and check for a.nil? to be
true. Or perhaps better just rely on the fact that nil is false in
Ruby. Using nil will be equivalent to "undef $a" in Perl.

···

On 2004-06-16 02:19:07 +0900, tony summerfelt wrote:

--
lambda { |c| lambda { |f| f[f] } [ lambda { |f| c[lambda { |x| f[f] } ] }] }

Don't check for defined, check for nil. It's virtually the same thing, unless
there's a chance that Delta_DHMS returns nil as a real return value.

  Sean O'Dell

···

On Monday 14 June 2004 14:58, tony summerfelt wrote:

On Tue, 15 Jun 2004 05:31:30 +0900, you wrote:
>What about the logic of your code or design depends on the 'existence'
>of a variable? What problem is it you're trying to solve with this
>approach?

just makes the code shorter. here's an excerpt of a log trimming
program in perl (for the format that binkd generates) ('@' precedes
arrays in perl):

while(<binkd>)
{
    # date parsing code was here
     @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
     print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);
     next if defined(@diff);
     print $trimmed $_ if ! /(\[\d+\])/;
     undef(@diff);
}

this goes through each line in the log file.
if the log line contains a date stamp, it's processed and written to
an archive file if it meets the criteria, and the next line in the
file is read.

tony summerfelt <snowzone5@hotmail.com> writes:

{
    # date parsing code was here
     @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
     print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);
     next if defined(@diff);
     print $trimmed $_ if ! /(\[\d+\])/;
     undef(@diff);
}

Can't you just use "=nil" to achive the same thing?

i.e. something like:

diff = Delta_DHMS(binkdate, today) if /(\[\d+\])/
print trimmed $_ if diff[0] < ARGV[1] && diff
next if diff
print trimmed $_ if ! /(\[\d+\])/
diff = nil

(just using the fact that 'nil' is false)

···

--
Josh Huber

testing whether diff is defined won't work in ruby anyway. Any time you have an expression like this:

   foo = 23 if expression

foo ends up being automagically defined anyway. After running that code, if expression is false, foo == nil.

So, as Sean says, it would probably be better to use nil, unless Delta_DHMS might return nil itself.

cheers,
Mark

···

On Jun 14, 2004, at 2:58 PM, tony summerfelt wrote:

while(<binkd>)
{
    # date parsing code was here
     @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
     print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);
     next if defined(@diff);
     print $trimmed $_ if ! /(\[\d+\])/;
     undef(@diff);
}

tony summerfelt wrote:

What about the logic of your code or design depends on the 'existence'
of a variable? What problem is it you're trying to solve with this
approach?
   
just makes the code shorter. here's an excerpt of a log trimming
program in perl (for the format that binkd generates) ('@' precedes
arrays in perl):

while(<binkd>)
{
   # date parsing code was here
    @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
    print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);

Here you check that @diff is defined after trying to access an element of diff, is that right?

    next if defined(@diff);
    print $trimmed $_ if ! /(\[\d+\])/;
    undef(@diff);
}

How about this (untested)?

while(binkd)
    # date parsing code was here
     diff=Delta_DHMS(binkdate, today) if /(\[\d+\])/
     print $trimmed $_ if diff && diff[0] < ARGV[1] next if diff
     print $trimmed $_ if ! /(\[\d\])/
     diff = nill
end

···

On Tue, 15 Jun 2004 05:31:30 +0900, you wrote:
     
--
Mark Sparshatt

I think the whole point here is that it isn't Ruby-ish

i'm slowly learning the ruby way to do things...

If you know Ruby well, there is almost certainly a way to do it that is
just as reasonable and sensical as the Perl way, but it would be
sensical for Ruby.

i get the feeling i'm well on my way once i finish my current
project...

into Ruby, I would (assuming that Delta_DHMS() won't return nil) write
'next unless diff.nil?', then later, 'diff = nil'. If there's a chance
that the method might return nil, you can always use the trick Sean
posted elsewhere on this thread.

of course, i don't want to force ruby code to look/act like perl.
but i DO want to keep 'the ruby way' if at all possible. later on
when i know ruby a lot better and i have to go back to this code it
won't be too embarrassing :slight_smile:

sometimes thinking in perl hampers me when i'm working in another
language...

···

On Wed, 16 Jun 2004 03:45:50 +0900, you wrote:

For the sake of it:

def test(); p defined? x; x = "hello"; p defined? x; end
test() # => nil, "local-variable"

According to the definition of "defined" implemented by
defined?(), it appears that in fact a local variable is
not defined until it gets assigned. That necessarily
happens at runtime. However, at parse time (or eval time),
the compiler determines that some entity is going to be
a local variable... once it gets defined at runtime.

This is a very minor thing and I would be surprised
to seen some example of code taking advantage of that
behavior of defined?()

Yours,

JeanHuguesRobert

···

On Jun 15, 2004, at 10:19 AM, tony summerfelt wrote:
I think the whole point here is that it isn't Ruby-ish to rely on a variable being defined or not. Ruby wassn't built to do things in that way; a couple examples in this thread show how variables are automagically defined when code is parsed. They aren't defined at runtime, they are defined at eval time.

-------------------------------------------------------------------------
Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17

Actually, Matz could probably very easily expose variables as objects
themselves to be manipulated like anything else in Ruby. I don't think
because he hasn't done it yet constitutes a "design decision" as much as
"something he didn't do." It's not impossible, in other words, it's just a
feature that doesn't exist yet.

  Sean O'Dell

···

On Tuesday 15 June 2004 11:45, Mark Hubbart wrote:

On Jun 15, 2004, at 10:19 AM, tony summerfelt wrote:
> On Tue, 15 Jun 2004 14:55:05 +0900, you wrote:
>>> I did not advocate removing, a.k.a. undefining,
>>> instance variable,
>
> it would be a local variable i'd be undefining, probably not an
> instance variable (although i'd like that option also)

I think the whole point here is that it isn't Ruby-ish to rely on a
variable being defined or not. Ruby wassn't built to do things in that
way; a couple examples in this thread show how variables are
automagically defined when code is parsed. They aren't defined at
runtime, they are defined at eval time. So basically, If you are
translating code from Perl that undefines local variables, you will
have to find a different way of doing it, due to the way Ruby was
designed. I doubt that this is likely to change, because it's part of
how Ruby was designed.

In your code you used global variables, and they work different
in Perl than you seem to think.

actually i used local variables, the code was an excerpt...

So you can do "a = nil" or "$a = nil" and check for a.nil? to be
true. Or perhaps better just rely on the fact that nil is false in
Ruby. Using nil will be equivalent to "undef $a" in Perl.

that seems to be the way to go...when i know ruby better my question
will probably be moot :slight_smile:

···

On Wed, 16 Jun 2004 07:03:25 +0900, you wrote:

Oh! Which brings to mind something really neat I figured out awhile ago. If
Delta_DHMS really can return nil as a valid value, try re-writing the code
like this:

{
    # date parsing code was here
     @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
     print $trimmed $_ if $diff[0] < $ARGV[1] && @diff != :undefined;
     next if @diff != :undefined;
     print $trimmed $_ if ! /(\[\d+\])/;
     @diff = :undefined;
}

Initialize @diff = :undefined in your class initialize method. :undefined
will be a Ruby symbol that gets created on its first use. From there on out,
just set @diff to :undefined whenever you need to "undefine" it.

  Sean O'Dell

···

On Monday 14 June 2004 15:47, Mark Hubbart wrote:

On Jun 14, 2004, at 2:58 PM, tony summerfelt wrote:
> while(<binkd>)
> {
> # date parsing code was here
> @diff=Delta_DHMS(@binkdate,@today) if /(\[\d+\])/;
> print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);
> next if defined(@diff);
> print $trimmed $_ if ! /(\[\d+\])/;
> undef(@diff);
> }

testing whether diff is defined won't work in ruby anyway. Any time you
have an expression like this:

   foo = 23 if expression

foo ends up being automagically defined anyway. After running that
code, if expression is false, foo == nil.

So, as Sean says, it would probably be better to use nil, unless
Delta_DHMS might return nil itself.

in perl it's null. which is what defined() and undef() test for...

···

On Tue, 15 Jun 2004 07:35:33 +0900, you wrote:

Can't you just use "=nil" to achive the same thing?
(just using the fact that 'nil' is false)

testing whether diff is defined won't work in ruby anyway. Any time you
have an expression like this:

  foo = 23 if expression

foo ends up being automagically defined anyway. After running that
code, if expression is false, foo == nil.

yeah, like i said undef would be great :slight_smile:

So, as Sean says, it would probably be better to use nil, unless
Delta_DHMS might return nil itself.

that was just one method from an external perl module, and i when
successful returns an array...not sure if it can return a null or
not...either way it's just as easy to use defined/undef in perl...

···

On Tue, 15 Jun 2004 07:47:06 +0900, you wrote:

    print $trimmed $_ if $diff[0] < $ARGV[1] && defined(@diff);

Here you check that @diff is defined after trying to access an element
of diff, is that right?

that perl code means a line read from the log file is written to an
archive file IF the date matches the criteria AND that @diff exists

    print $trimmed $_ if diff && diff[0] < ARGV[1]

except that in this case @diff may contain a '1' or other garbage. to
avoid that, it's undefined and only defined when it's assigned valid
data.

before i settled on that particular line of code, i tried other
things...that was the shortest that worked...

···

On Tue, 15 Jun 2004 14:32:15 +0900, you wrote:

Yes, I agree, it is possible that Matz could implement that. I think though that it would be less of an addition than a conversion. For example:

   foo = 23 unless true
   p defined? foo

Will print "local-variable". The code foo in which foo was assigned to was not run, so the '=' operator was never really applied to it. So if there was a Variable class, and the '=' operator was its method, that method would not be called in the above code. Because of this, I strongly suspect the above would print "nil" if there was a Variable class.

I may not be understanding it fully (I'm self-taught, there are many gaps in my knowledge) but it *looks* like a design decision to me, and 'variables as objects' couldn't be implemented without a non-trivial change to the way the language works. But I could easily be wrong :slight_smile:

cheers,
Mark

···

On Jun 15, 2004, at 1:38 PM, Sean O'Dell wrote:

On Tuesday 15 June 2004 11:45, Mark Hubbart wrote:

On Jun 15, 2004, at 10:19 AM, tony summerfelt wrote:

On Tue, 15 Jun 2004 14:55:05 +0900, you wrote:

I did not advocate removing, a.k.a. undefining,
instance variable,

it would be a local variable i'd be undefining, probably not an
instance variable (although i'd like that option also)

I think the whole point here is that it isn't Ruby-ish to rely on a
variable being defined or not. Ruby wassn't built to do things in that
way; a couple examples in this thread show how variables are
automagically defined when code is parsed. They aren't defined at
runtime, they are defined at eval time. So basically, If you are
translating code from Perl that undefines local variables, you will
have to find a different way of doing it, due to the way Ruby was
designed. I doubt that this is likely to change, because it's part of
how Ruby was designed.

Actually, Matz could probably very easily expose variables as objects
themselves to be manipulated like anything else in Ruby. I don't think
because he hasn't done it yet constitutes a "design decision" as much as
"something he didn't do." It's not impossible, in other words, it's just a
feature that doesn't exist yet.

tony summerfelt <snowzone5@hotmail.com> writes:

in perl it's null. which is what defined() and undef() test
for...

I'm aware what they do, but you can get the desired behavior
using nil. I mean, you're trying to use Ruby, not Perl right?

···

--
Josh Huber