Controlled block variables

Then why isn't it being ignored on core? D.N.C.

Are you implying that it is stupid, dumb and unworthy? Then speak for youself.
I believe such matters tend to get ignored on ruby-talk b/c there is too much
"filter-noise" there for more indepth and speculative analyses to shine
through, among other reasons --like constant nay-sayers who bark down an idea
for no other reason then it's outside the "general norms".

This belongs on ruby-talk? Fine...

For those interested, see reference core:1787, and start of thread 1751

  http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/1787
  http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/1751

-t0

···

On Wednesday 26 November 2003 09:10 am, Guy Decoux wrote:

I'm agree with David : this thread has *nothing* to do with ruby-core.

Your subject is appropriated for ruby-talk : if it's ignored, like you
say, this is perhaps because there is a good reason

Are you implying that it is stupid, dumb and unworthy?

You want to change this

   a = 12

   def b
      p a
   end

Nobody has a problem with this, except you, perhaps because you are
learning ruby ?

ruby-core:1728 and ruby-talk:86133 are another good examples

Guy Decoux

I actually have wondered in the past why there isn’t an #eval that takes
a proc (other than as a binding).

There’s #instance_eval and #module_eval/#class_eval for replacing the
object scope of a Proc, but
there’s no way you can do this:

def foo
a = 4
b = 5

proc { p a; p b }

end

def bar§
a = 7
b = 8

eval p

end

bar(foo)

and get 7 and 8 printed. I realize that Proc objects are closures, but
since they’re also representations
of sections of code, it would be interesting to be able to switch them
to dynamic scoping for all the
benefits and problems that causes, and using #eval seems like a fairly
clean way of denoting that.

Of course, I don’t know how big a change that would require for Proc and
the Ruby interpreter. I’m
not familiar with the internals of either.

Regards.

  • Dan

No and Always.

No, because that’s not what I orignially presented. I offered an idea that
would allow eval an exception to reach up to that scope, not the above def.
I later asked, why it was the def could not see a in this case, and had some
interesting return dialog, to which I then added an idea on how it could
work. So other then for eval, I never suggested that Ruby be changed to do
that. I was only disscussing some interesting notions on the topic.

And I am Always learning Ruby, since my conversion in 2001. Perhaps you are
not ?

-t0

P.S. You know, I don’t really like being antagonistic. But it is really
bothersome to have to deal such negativity. If you find the concept somehow
flawed then present an intelligent counter argument, don’t just berail me for
having a notion all my own. And if you don’t feel the disccussion belongs on
core then just say “Hey, guys, this should probably be on ruby-talk, can we
move it there?” Or, “Perhaps another list would be a good idea…” Rather
then being so accustional, as if we had violated some hallowed law.

···

On Wednesday 26 November 2003 09:56 am, ts wrote:

Are you implying that it is stupid, dumb and unworthy?

You want to change this

a = 12

def b
p a
end

Nobody has a problem with this, except you, perhaps because you are
learning ruby ?

ruby-core:1728 and ruby-talk:86133 are another good examples

Except that it means more work for interpreter to enforce rule of not allowing it. Would you say the same thing about this?

class WhatDoIDo

def dothis
print “Nope”
end

def dothis
print “Yep”
end

end

To think this makes me look like a nubie! HAH! I think you made too much of an
assumption and thus did not really understand me. perhaps other did not
understand either, so I will clear up.

The point was that this is completely allowed. The previous def just gets
replaced by the next one. This was in response to

Agreed 100% - I see no reason for allowing several hooks
in the same class.

Does it make sense now?

As for 1728, I really had just never done that before. I have always defined
my classes prior to substantiating any object. Never even occured to me that
if I susbsequently altered my classes that all my objects would change too.

-t0

···

On Wednesday 26 November 2003 09:56 am, ts wrote:

Hi –

···

On Wed, 26 Nov 2003, Dan Doel wrote:

I actually have wondered in the past why there isn’t an #eval that takes
a proc (other than as a binding).

There’s #instance_eval and #module_eval/#class_eval for replacing the
object scope of a Proc, but
there’s no way you can do this:

def foo
a = 4
b = 5

proc { p a; p b }

end

def bar(p)
a = 7
b = 8

eval p

end

bar(foo)

and get 7 and 8 printed. I realize that Proc objects are closures, but
since they’re also representations
of sections of code, it would be interesting to be able to switch them
to dynamic scoping for all the
benefits and problems that causes, and using #eval seems like a fairly
clean way of denoting that.

I can see what you’re getting at, but I don’t agree that it’s clean,
because it involves so much magic; in particular, both the program and
the programmer would have to know what the names of the variables from
the proc’s creation context were, which means things get very
unencapsulated and very coupled.

David


David A. Black
dblack@wobblini.net

this is an interesting means of code evaluation. essentially encapsulating
blocks of code to be “opened-up” (like a can of worms :wink: at other points in
execution. it is a technique quite capable of replacing methods/functions all
together. but there is a severe problem with it: it causes bad headaches with
name clashing. this is why methods are used instead. with methods you at
least know what is going into them and variables are renamed in transition.
for example what if i was using the variable x instead of a? i’d have to set
a = x, but what if i was already using a for something else, then i’d have to
move a out of the way. and so forth.

so what you end up doing instead is

def foo
a = 4
b = 5
proc { |a,b| p a; p b }
end
def bar(p)
a = 7
b = 8
p.call(a,b)
end
bar(foo)

and you’ll get 7 and 8 without the problem sited above.

that said, now perhaps someone can explain to me why the #call is need? is
there some reason the interpretor can’t deal with just

p(a,b)

couldn’t Ruby just give precedence to proc evaluation similiar to local
precedence?

thanks Dan,
-t0

···

On Wednesday 26 November 2003 03:57 pm, Dan Doel wrote:

I actually have wondered in the past why there isn’t an #eval that takes
a proc (other than as a binding).

There’s #instance_eval and #module_eval/#class_eval for replacing the
object scope of a Proc, but
there’s no way you can do this:

def foo
a = 4
b = 5

proc { p a; p b }

end

def bar(p)
a = 7
b = 8

eval p

end

bar(foo)

and get 7 and 8 printed. I realize that Proc objects are closures, but
since they’re also representations
of sections of code, it would be interesting to be able to switch them
to dynamic scoping for all the
benefits and problems that causes, and using #eval seems like a fairly
clean way of denoting that.

Hi T,

maybe you can make use of “define_method” as in

class X
def self.add_method name, value
eval "define_method name, proc{value}"
end
end

X.add_method :array, [1, 2, 3]
X.add_method :hash, {1=>“A”, 2=>“B”}

x = X.new

p x.array # => [1, 2, 3]
p x.hash # => {1=>“A”, 2=>“B”}

HTH

Regards,
Pit

Agreed 100% - I see no reason for allowing several hooks
in the same class.

Does it make sense now?

svg% ruby -w
class A
   def a:hook
   end

   def a:hook
   end
end
^D
-:5: warning: method redefined; discarding old a:hook
svg%

p.s. : gsub!(/hook/, 'wrap')

Guy Decoux

David A. Black wrote:

I can see what you’re getting at, but I don’t agree that it’s clean,
because it involves so much magic; in particular, both the program and
the programmer would have to know what the names of the variables from
the proc’s creation context were, which means things get very
unencapsulated and very coupled.

Actually, I meant that the way of specifying that you want dynamic
scoping was clean.
If Proc had another method similar to #call that used dynamic scoping,
that’d be rather
weird, but “eval proc” seems to convey the idea without talking about
lexical scoping
and dynamic scoping at all.

That said, dynamic scoping isn’t for everyone. Common Lisp is, for the
most part,
dynamically scoped, which I personally don’t like, but it has its uses.
For example:

(let ((print-circle t))
(print some-circular-data-structure))

Where (print) uses the flag print-circle flag to determine whether or
not to safely
print circular lists. print-circle is seen as true in that call, but
it may not be in the
general global environment. The alternative would be:

(let ((old-pcircle print-circle))
(setf print-circle t)
(print some-circular-data-structure)
(setf print-circle old-pcircle))

Dynamic scoping isn’t for everyone (like I said, I don’t like it much),
but it can have its
uses.

On the other hand, I’m not sure how generally useful this would be in
Ruby, as
global-ish flags like print-circle would certainly be frowned upon,
and it would only
be available in Procs, and one doesn’t normally use Proc objects in
global variables
as print routines. Perhaps someone smarter than I will come up with
something using
dynamic scoping that would be otherwise tedious in Ruby.

Anyhow, I’m not overly attached to the idea. It was more of a what
if/why don’t we
have this ramble.

  • Dan

You know I actually just noticed that the other day. And to be honest I would
just never do it, b/c I would look at my code and immediately think Array or
Hash. Poor semantic distinction == much confusion == difficult code
maintainence.

-t0

···

On Wednesday 26 November 2003 07:42 pm, Dave Brown wrote:

In article 200311260920.29155.transami@runbox.com,

T. Onoma transami@runbox.com wrote:
: that said, now perhaps someone can explain to me why the #call is need?
: is there some reason the interpretor can’t deal with just
:
: p(a,b)
:
: couldn’t Ruby just give precedence to proc evaluation similiar to local
: precedence?

p[a,b] will do as you expect. Proc# actually calls the code in
a Proc object.

T. Onoma wrote:

that said, now perhaps someone can explain to me why the #call is need? is
there some reason the interpretor can’t deal with just

p(a,b)

couldn’t Ruby just give precedence to proc evaluation similiar to local
precedence?

This was discussed over the summer as I recall. It opens up a whole can
of worms.

For example, function calling syntax for Ruby can be either

p(a,b)

or

p a, b

So do you allow callable objects in the latter mode? This is all
essentially making
functions/methods first class in Ruby. However, if you do this, then while

foo.meth arg1, arg2, ...

is clear,

foo.meth

isn’t. It could either be the first class method ‘meth’ of the object
‘foo’, or the result
of calling the method ‘meth’ of ‘foo’. In other words, you need to
switch to explicit
method call semantics like Python:

foo.meth is a method object,
foo.meth() is the result of calling the method

So if you allow callable objects, and run it to its logical conclusion,
you end up
needing parentheses (which I don’t think everyone’s wild about).

I’m sure there’s stuff I’m leaving out. Search the ruby-talk archives
for the whole
big discussion if you’re interested.

  • Dan

And I am Always learning Ruby, since my conversion in 2001. Perhaps you

are # not ?

Maybe nobody recognizes you because you’re constantly changing your name?
Are you Tom Sawyer, Transami, or T. Onoma?

And you seem to come and go in bursts. You disappeared for a while and
then came back suddenly as T. Onoma as probably the single most prolific
poster on ruby-talk (and ruby-core).

Understood. So I will set the record straight for all to bare.

My real name is Tom Sawyer. As you can imagine, combined with other character
traits of mine, the name tends to take on a life of its own. So instead, I
used my email name Transami, and did so for some time. As many of you will
remember.

Then very bad things happened to me, that are not really suitable to open
disscusion. (But so that there is no misconcption, I will embaressingly admit
it is because my mind is “too loud” and my heart “too sensitive”) So I had
to go away for awhile. Only recently have I ventured back into parts of the
real world. So when I returned here I used a psuedo name, T. Onoma, in an
irrational attempt to be not so me. If that makes any sense. But obviously
there seems to be no changing facts. “I post, therefore I am”. Well, not
really, I post a lot b/c I have no life, friends, job, etc. So there you go.
Now you know. I am vulnerable.

It’s easy to understand how someone might think you’re just learning Ruby.
Don’t be so sensitive, Tom. :slight_smile:

I will try. Thank you.

-Tom

···

On Wednesday 26 November 2003 12:41 pm, Chad Fowler wrote:

On Wed, 26 Nov 2003, T. Onoma wrote:

So we should throw an error instead? I say we don’t even need the warning.
So ask, should it continue to do so with the addition of hooks? (Not to
mention there are some fundemental problems with this disallowing.)

-t0

···

On Wednesday 26 November 2003 04:11 pm, ts wrote:

Does it make sense now?

svg% ruby -w
class A
def a:hook
end

def a:hook
end
end
^D
-:5: warning: method redefined; discarding old a:hook
svg%

I’ll respond here to keep core as prestine as some seem to want it to be.
Which is fine but indicates to me that we could use a second list for such
things. Anyway.

Sorry I let this slip by, I wanted to think on it more. And though I have, I
must admit I’m not quite seeing it --quite possibly my small brain just isn’t
cutting it :slight_smile: But perhaps too, there’s a communication disconnect. So let me
lay down the core problem and you show me how your solution solves it. That
should tell us if were on the same page.

a = [1,2,3]
class_eval {
def ameth
p a
end
}

So the problem is, a will be eval’d as nil, since it is outside of def. To
overcome I must convert a to a literal and stick it in a string.

a = [1,2,3]
a = “[#{a.join(‘,’)}]”
class_eval %Q{
def ameth
p #{a}
end
}

So how does you solution deal with this problem?

For comparison I will point out Ryan’s solution. Ryan created an object pool
that has a global scope, then created a special method in the Object class
that adds any object to the pool, so one then does something like:

a = [1,2,3]
a.to_pool
class_eval {
def ameth
p Pool.a
end
}

Of course, there is also the solution:

a = [1,2,3]
$a = a
class_eval {
def ameth
p $a
end
}

While I like Ryan’s solutions b/c it just seems like a useful thing to have an
object pool handy without resorting to global variables, one can easily say
these are hacks. And for the problem at hand there isn’t actually a solution
that isn’t. But it is certainly interesting to see who can come up with the
best one.

-t0

···

On Wednesday 26 November 2003 12:05 pm, Pit Capitain wrote:

maybe you can make use of “define_method” as in

class X
def self.add_method name, value
eval “define_method name, proc{value}”
end
end

X.add_method :array, [1, 2, 3]
X.add_method :hash, {1=>“A”, 2=>“B”}

x = X.new

p x.array # => [1, 2, 3]
p x.hash # => {1=>“A”, 2=>“B”}

I see. And I’ll check the archives to learn more (although that search
function is not so great).

But I wonder, couldn’t the only exception be made for Proc? So without the
perens a Proc is a Proc, with perens it’s evaluated.

 foo.aproc is a Proc object,
 foo.aproc() is the result of calling the Proc

This kind of distinction is already made with locals vs. methods. Just b/c
Procs face the problem doesn’t mean it has to be extend to all. Or am I
missing something further?

-t0

···

On Wednesday 26 November 2003 10:24 pm, Dan Doel wrote:

So do you allow callable objects in the latter mode? This is all
essentially making
functions/methods first class in Ruby. However, if you do this, then while

foo.meth arg1, arg2, ...

is clear,

foo.meth

isn’t. It could either be the first class method ‘meth’ of the object
‘foo’, or the result
of calling the method ‘meth’ of ‘foo’. In other words, you need to
switch to explicit
method call semantics like Python:

foo.meth is a method object,
foo.meth() is the result of calling the method

So if you allow callable objects, and run it to its logical conclusion,
you end up
needing parentheses (which I don’t think everyone’s wild about).

I’m sure there’s stuff I’m leaving out. Search the ruby-talk archives
for the whole
big discussion if you’re interested.

So ask, should it continue to do so with the addition of hooks? (Not to
mention there are some fundemental problems with this disallowing.)

Which problems ?

Guy Decoux

From T. Onama:

Sorry I let this slip by, I wanted to think on it more. And though I
have, I must admit I’m not quite seeing it --quite possibly my small
brain just isn’t cutting it :slight_smile: But perhaps too, there’s a
communication disconnect. So let me lay down the core problem and you
show me how your solution solves it. That should tell us if were on the
same page.

a = [1,2,3]
class_eval {
def ameth
p a
end
}

So the problem is, a will be eval’d as nil, since it is outside of def.

Actually, this is the problem:
NoMethodError: undefined method `class_eval’ for main:Object

Or did you mean the above code to exist within a class? If so, I have:

class X
a = [1,2,3]
class_eval {
def ameth
p a
end
}
end

X.new.ameth

NameError: undefined local variable or method `a’ for #<X:0x101695f8>

from (irb):13:in `ameth’

So ‘a’ is not evaluated as nil, it cannot be evaluated.

To overcome I must convert a to a literal and stick it in a string.

class Y
a = [1,2,3]
class_eval %Q{
def ameth
p #{a.inspect}
end
}
end

Y.new.ameth # => “[1, 2, 3]”

So how does you solution deal with this problem?

I hate to ask at this late stage, but what’s the problem? If you want to
make the value ‘a’ available to the dynamically created method ‘ameth’,
maybe you could try this

class Z
@@a = [1,2,3]
class_eval {
def ameth
@@a.length
end
}
end

Z.new.ameth # => 3

If you don’t know in advance what your variable names are going to be, use
a hash. You don’t have to resort to global variables; class variables are
there to help. And so am I :slight_smile:

Gavin

From T. Onama:

But I wonder, couldn’t the only exception be made for Proc? So without
the perens a Proc is a Proc, with perens it’s evaluated.

 foo.aproc is a Proc object,
 foo.aproc() is the result of calling the Proc

This kind of distinction is already made with locals vs. methods. Just
b/c Procs face the problem doesn’t mean it has to be extend to all. Or
am I missing something further?

On http://ruby-doc.org, you can find a link to “Ruby Eye for the Python
Guy”, which contains a link to an explanation of the difference between
Python and Ruby in terms of “methods as first class objects”. That
document, on onestepback.org, is essential reading.

In short, the message-passing paradigm is paramount in Ruby. You may say
that ‘foo.aproc is a Proc object’, but the reality is that ‘foo.aproc’ is
the result of sending the message ‘aproc’ to ‘foo’. Nothing more, nothing
less. And there are good reasons why that won’t change. Making parens
optional is just a superficial reason.

Gavin