Request for Block local methods, and Proc syntax

So after using Ruby for a little over two months, I've made the complete
switch from Java to Ruby and I'm loving it.

But I have two features that I would like to add to Ruby if possible.
Would you guys be able to tell me if these features are
consistent/possible?

1) Block local methods:

def myMethod
  def myLocalMethod #<-- myLocalMethod only visible within myMethod()
  end
end

This doesn't look like much at first. But it's extremely useful for
meta-programming. Right now, people are using instance_eval to get
around this, which creates some scoping problems.

we can do stuff like this:

def html(&block)
  block.instance_eval do
    def image
    end
  end
end

which we can use like this:

html do
  image()
end

2) Procs without proc keyword.

Is there any reason why we need a proc keyword in front of a block?

Wouldn't it be cleaner if every do/end or {} created a block? Then most
language constructs can be user-defined:

for example we can write this:

while {x} do
  puts "a"
end

where "while" is just a method that takes two block arguments.

We can even write our own object system:

klass MyKlass do
  defMethod :ourMethod do
    puts "cool huh?"
  end
end

Please let me know what you think.
  -Patrick

···

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

So after using Ruby for a little over two months, I've made the complete
switch from Java to Ruby and I'm loving it.

But I have two features that I would like to add to Ruby if possible.
Would you guys be able to tell me if these features are
consistent/possible?

1) Block local methods:

def myMethod
def myLocalMethod #<-- myLocalMethod only visible within myMethod()
end
end

This doesn't look like much at first. But it's extremely useful for
meta-programming. Right now, people are using instance_eval to get
around this, which creates some scoping problems.

we can do stuff like this:

def html(&block)
block.instance_eval do
   def image
   end
end
end

which we can use like this:

html do
image()
end

This does not really make sense. block.instance_eval evaluates the
block with self set to "block". But inside the block where you invoke
image() self is assigned to what it was before invocation of method
html.

To achieve what you want you do not need a new feature in Ruby:

irb(main):001:0> def html(&block)
irb(main):002:1> context = Object.new
irb(main):003:1> def context.image
irb(main):004:2> puts "An image"
irb(main):005:2> end
irb(main):006:1> context.instance_eval &block
irb(main):007:1> end
=> nil
irb(main):008:0> html do
irb(main):009:1* puts "intro"
irb(main):010:1> image
irb(main):011:1> puts "extro"
irb(main):012:1> end
intro
An image
extro
=> nil
irb(main):013:0>

2) Procs without proc keyword.

Is there any reason why we need a proc keyword in front of a block?

To disambiguate an empty Hash from an empty block.

Wouldn't it be cleaner if every do/end or {} created a block? Then most
language constructs can be user-defined:

for example we can write this:

while {x} do
puts "a"
end

where "while" is just a method that takes two block arguments.

You can simply work around this by doing something like

def l(&b)
  b
end

Then you can do "l{x}"

We can even write our own object system:

klass MyKlass do
defMethod :ourMethod do
   puts "cool huh?"
end
end

What exactly is this supposed to do? Where does creating a block
without "proc" or "lambda" play a role here?

Please, do not easily jump to asking for language changes. Most of
the time it turns out that things are the way they are for a reason
and usually there is a solution that does not involve changing the
language.

Cheers

robert

···

2008/9/1 Patrick Li <patrickli_2001@hotmail.com>:

--
use.inject do |as, often| as.you_can - without end

Patrick Li wrote:

2) Procs without proc keyword.

Is there any reason why we need a proc keyword in front of a block?

Well, it's not exactly what you're looking for, but Ruby 1.9 has
introduced the "->" notation for closures. It takes a bit of getting
used to, but personally I rather like it. See
http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l9 for more info
(except it's no longer experimental).

-Josh

···

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

http://drawohara.com/post/48758159/ruby-temporary-methods-for-dsls

a @ http://codeforpeople.com/

···

On Aug 31, 2008, at 8:35 PM, Patrick Li wrote:

1) Block local methods:

def myMethod
def myLocalMethod #<-- myLocalMethod only visible within myMethod()
end
end

This doesn't look like much at first. But it's extremely useful for
meta-programming. Right now, people are using instance_eval to get
around this, which creates some scoping problems.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Hi,

1) Block local methods:

def myMethod
def myLocalMethod #<-- myLocalMethod only visible within myMethod()
end
end

In that case, if myLocalMethod can only be visible from myMethod, can
we say the receiver responds to myLocalMethod message, or not? I am
afraid such "local methods" risk break the language's object system.

It's much easier to make such inner def to define a singleton method for
the receiver, and I have ever considered it, but I didn't get
confidence on the idea.

2) Procs without proc keyword.

Is there any reason why we need a proc keyword in front of a block?

This idea has risk to break the syntax. Making keyword less braces a
block conflict existing syntax (a lot). The idea should be realized
in the different language, I think.

              matz.
p.s.
Try not to change the language first. Try bend it.

···

In message "Re: Request for Block local methods, and Proc syntax" on Mon, 1 Sep 2008 11:35:56 +0900, Patrick Li <patrickli_2001@hotmail.com> writes:

The reason instance_eval shouldn't be used in that way is because it
interferes with your scope in a very unintuitive way.

For example, you can't do something like this:

@source = "pic.gif"
html do
  image(@source)
end

You have to do something like this:
source = @source
html do
  image(source)
end

The reason, also, that I ask for a simpler syntax for procs, is so that
we can eliminate the kludgy block argument syntax. I like Ruby, but I
feel it's power is limited because of the complexity of it's syntax.

Smalltalk is *almost* like Ruby, except that it treats blocks (or
closures as they call it) consistently, which makes it possible to write
many control structures.

···

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

Thanks for your input guys.

I want to say that I do really like Ruby. I'm just probing to see if
there's improvements that can still be made, or whether it's as good as
it can be already.

Oh, and I do realize the ambiguity of my last example.

Here's my thoughts on that:

I think you should ALWAYS be able to retrieve the "context" of an object
given an object reference.

In compiled, statically-typed languages such as C++ or Java.
objects can access their "class context" by using:
obj.class

They cannot access their "block context", by well they don't have to,
because Java blocks aren't first-class objects like they are in Ruby.

I think, given an object, you should be able to access their
"block"/"scope", because Ruby actually treats them as first-class
objects.

So my example would look something like this:

block.scope.instance_eval do
  def myMethod
  end
end

Anyway, thanks for the discussion. It's nice to read a thoughtful
response.
  -Patrick

PS: I am actually currently investigating Smalltalk. I like the syntax,
and the system, but Ruby does have one big advantage over it. It's
standardized.
I can't even find a book that discusses the Smalltalk in depth, because
there's so many different versions.

···

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

Thanks for the reply Matz,

I see what you mean by the inner def screwing up the object system. I
don't foresee an easy way around that yet.

But I still think it's worth thinking about. In my opinion, DSL's is
Ruby's greatest strength. It's the one feature where Ruby is light years
ahead of other languages. And context-sensitive methods are vital to
DSL's. I think putting in some thought towards this direction could
really make Ruby stand out.

What other language let's you write code like:

html{
  image(@mySource)
}

or

initEngine{
  initSound
  initGraphics
  @window = initWindow
}

Anyway, thanks for designing such an elegant language Matz. It's really
a joy to use. I'm just shamelessly asking for more.
  -Patrick

···

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

The reason instance_eval shouldn't be used in that way is because it
interferes with your scope in a very unintuitive way.

For example, you can't do something like this:

@source = "pic.gif"
html do
image(@source)
end

You have to do something like this:
source = @source
html do
image(source)
end

That's true. I have to admit that I can't remember having seen this
as a problem - it's probably a matter of programming style.

The reason, also, that I ask for a simpler syntax for procs, is so that
we can eliminate the kludgy block argument syntax. I like Ruby, but I
feel it's power is limited because of the complexity of it's syntax.

Umm, I have always thought of Ruby's syntax as clean and simple. :slight_smile:

You still have not explained how you would avoid the ambiguity with
your simple syntax...

Smalltalk is *almost* like Ruby, except that it treats blocks (or
closures as they call it) consistently, which makes it possible to write
many control structures.

Well, you do not _have_ to use Ruby... If I would constantly miss
features of another language X this would be the very moment when I'd
start considering using X instead of Ruby. And if it happens only
from time to time I'd rather try to find a workable alternative vs.
changing the language. My 0.02 EUR.

Kind regards

robert

···

2008/9/1 Patrick Li <patrickli_2001@hotmail.com>:

--
use.inject do |as, often| as.you_can - without end

Thanks for your input guys.

You're welcome!

I want to say that I do really like Ruby. I'm just probing to see if
there's improvements that can still be made, or whether it's as good as
it can be already.

I have a different approach: I like the challenge to get things
working - without trying to change the language. Actually I believe,
most of the time language changes are not worthwhile because of the
huge potential to wreck havoc on code - and if the language changes a
lot code is affected. You can see that from discussions and change
notices for even the comparatively small changes that have been done
for 1.9.

Oh, and I do realize the ambiguity of my last example.

Here's my thoughts on that:

I think you should ALWAYS be able to retrieve the "context" of an object
given an object reference.

How does this help the parser in detecting whether it's a proc /
lambda or a Hash? Runtime access to the binding does not help here at
all.

In compiled, statically-typed languages such as C++ or Java.
objects can access their "class context" by using:
obj.class

Well, yes, but with significant differences to Ruby. C++ has
extremely limited capabilities in that area. Did you mean C#?

They cannot access their "block context", by well they don't have to,
because Java blocks aren't first-class objects like they are in Ruby.

Actually, you can have a kind of closures in Java as well - although
not as elegant as in Ruby.

interface Foo {
  void bar();
}

public static void doit(Foo f) {
  f.bar();
}

public static void test() {
  final int i = 10;
  doit( new Foo() {
    void bar() {
      System.out.println("i is " + i);
    }
  } );

I think, given an object, you should be able to access their
"block"/"scope", because Ruby actually treats them as first-class
objects.

There is no general "scope" of an object since you can have multiple
references to any object. The notion of "scope of an object" does not
make sense in Ruby.

Btw, your functionality can be achieved without language changes by
applying a small change to my first version:

09:29:38 Temp$ ruby dm2.rb
intro
An image "test"
An image 999
extro
09:30:18 Temp$ cat dm2.rb
def html(&block)
  context = Object.new
  orig = eval("self", block.binding)
  orig.instance_variables.each do |var|
    context.instance_variable_set(var, orig.instance_variable_get(var))
  end

  def context.image(x)
    puts "An image #{x.inspect}"
  end

  context.instance_eval &block
end

@foo = "test"
def bar() 999 end

html do
  puts "intro"
  image @foo
  image bar
  puts "extro"
end

Cheers

robert

···

2008/9/2 Patrick Li <patrickli_2001@hotmail.com>:

--
use.inject do |as, often| as.you_can - without end

Hi,

···

In message "Re: Request for Block local methods, and Proc syntax" on Sun, 7 Sep 2008 01:08:01 +0900, Patrick Li <patrickli_2001@hotmail.com> writes:

But I still think it's worth thinking about. In my opinion, DSL's is
Ruby's greatest strength. It's the one feature where Ruby is light years
ahead of other languages. And context-sensitive methods are vital to
DSL's. I think putting in some thought towards this direction could
really make Ruby stand out.

You can switch the context (the receiver) using instance_eval. Do we
need more?

              matz.

So I thought about your code snippet a bit more Robert, and it's almost
what I need. Which is, the ability to access the local scope, but also
have access to the methods that are granted by the html-do-end method.

so in your example, you can now do this:

html do
  image(@source)
end

but you still can't do something this:

html do
  @code = retrieveCode
end
puts @code <-- doesn't work, because this is a different @code than the
one you assigned to.

I got around this by writing all the instance variables in "context" out
again at the end of the block. But it's not a very clean solution.

Is there anyway to retrieve the current block from within the block?
ie...

block = lambda do
  //bla bla bla
  //how does a block refer to itself?
end

Thanks
  -Patrick

···

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

I think we need a way to preserve the scope elegantly, so that methods
and instance variables can still be accessed.

The solutions posted so far are all pretty fragile still.

···

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

I got around this by writing all the instance variables in "context" out
again at the end of the block. But it's not a very clean solution.

Well, but it works remarkably well, doesn't it?

Is there anyway to retrieve the current block from within the block?
ie...

block = lambda do
//bla bla bla
//how does a block refer to itself?
end

As blocks have no conscience there is no way they know about
themselves - at least none that I would be aware of. :slight_smile:

Kind regards

robert

···

2008/9/4 Patrick Li <patrickli_2001@hotmail.com>:

--
use.inject do |as, often| as.you_can - without end

Hi --

So I thought about your code snippet a bit more Robert, and it's almost
what I need. Which is, the ability to access the local scope, but also
have access to the methods that are granted by the html-do-end method.

so in your example, you can now do this:

html do
image(@source)
end

but you still can't do something this:

html do
@code = retrieveCode
end
puts @code <-- doesn't work, because this is a different @code than the
one you assigned to.

I got around this by writing all the instance variables in "context" out
again at the end of the block. But it's not a very clean solution.

I personally dislike the "stealth" instance_eval, since it does indeed
look like instance variables belong to one object when they actually
belong to another. One thing you can do:

   class C
     def some_method
       yield self
     end
   end

   @a = 1
   C.new.some_method do |c|
     c.another_method(@a) # etc.
   end

so that you have the object you need but without changing 'self'
during the block.

David

···

On Thu, 4 Sep 2008, Patrick Li wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

sure you can:

require 'rubygems'
require 'tagz'
include Tagz.globally

content =
   html_{
     body_{
      @code = 42
     }
   }

puts @code

puts content

cfp:~ > ruby a.rb
42
<html><body>42</body></html>

you just have to be clever about when methods are in effect - check out the tagz source for an example of this.

alternatively you can skin it this way pushing and popping methods on the object in question:

cfp:~ > cat a.rb

content =
   html do
     body do
       img do
         @code = 42
       end
     end
   end

y 'content' => content, '@code' => @code

BEGIN {
   module Html
     Methods = lambda do
       def body &block
         "<body>#{ block.call }</body>"
       end

       def img &block
         "<img>#{ block.call }</img>"
       end
     end

     def Methods.new
       Module.new do
         module_eval &Methods
         def self.delete!() instance_methods.each{|m| remove_method m} end
       end
     end

     def Methods.push object
       singleton_class_for(object) do
         include(( @html_methods = Methods.new )) unless @html_methods
       end
     end

     def Methods.pop object
       singleton_class_for(object) do
         @html_methods.delete! if @html_methods
       end
     end

     def Methods.singleton_class_for object, &block
       singleton_class =
         class << object
           self
         end
       block ? singleton_class.module_eval(&block) : singleton_class
     end
   end

   def html &block
     Html::Methods.push self
     content = instance_eval(&block)
     "<html>#{ content }</html>"
   ensure
     Html::Methods.pop self
   end

   require 'yaml'
}

cfp:~ > ruby a.rb

···

On Sep 4, 2008, at 8:34 AM, Patrick Li wrote:

but you still can't do something this:

html do
@code = retrieveCode
end
puts @code <-- doesn't work, because this is a different @code than the
one you assigned to.

---
"@code": 42
content: <html><body><img>42</img></body></html>

you'll have to try harder than that before proposing changes to the language :wink:

cheers

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Hi --

···

On Sun, 7 Sep 2008, Patrick Li wrote:

I think we need a way to preserve the scope elegantly, so that methods
and instance variables can still be accessed.

The solutions posted so far are all pretty fragile still.

It sounds like you want some kind of bifurcation of self, so that
instance variables are resolved against one object and method calls
against another. I'm not sure how that would work, even theoretically,
and it sounds like it would be more fragile than just yielding an
object to a block.

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Mmm, that throws a wrench in things... well if I figure out how to do
proper dsl's with access to scope, I'll post it up here.

Thanks for your help and patience Robert

···

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

Hi David,
Mmm, I'm really not sure how it can be accomplished. I agree, yielding
an object to a block is a rock solid approach. It's a technique that I
love, and use everywhere. Which is actually, what led me to think about
this:

Everywhere in my code is stuff like this:

# from my event listening system...
listen do |listener|
  listener.listenTo(:playerKilledEvent) do
    ...
  end
end

# from my drawing system...
engine.drawFrame do |drawer|
  drawer.drawRect(...)
  drawer.drawCircle(...)
end

# from my collision system...
engine.detectCollision do |collider|
  @collided = collider.checkCollision(@myRect, @myCircle)
end

Which begs the question: Is there a better way?
  -Patrick

···

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

Hi --

···

On Sun, 7 Sep 2008, Patrick Li wrote:

Hi David,
Mmm, I'm really not sure how it can be accomplished. I agree, yielding
an object to a block is a rock solid approach. It's a technique that I
love, and use everywhere. Which is actually, what led me to think about
this:

Everywhere in my code is stuff like this:

# from my event listening system...
listen do |listener|
listener.listenTo(:playerKilledEvent) do
   ...
end
end

# from my drawing system...
engine.drawFrame do |drawer|
drawer.drawRect(...)
drawer.drawCircle(...)
end

# from my collision system...
engine.detectCollision do |collider|
@collided = collider.checkCollision(@myRect, @myCircle)
end

Which begs the question: Is there a better way?

Personally I do not at all rule out this in cases like those:

   drawer = engine.draw_frame
   drawer.draw_rect(...)
   drawer.draw_circle(...)

etc.

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!