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

  1. 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

2008/9/1 Patrick Li [email protected]:

def myLocalMethod #<-- myLocalMethod only visible within myMethod()
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>

  1. 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

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.

Patrick Li wrote:

  1. 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

2008/9/1 Patrick Li [email protected]:

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

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.

2008/9/2 Patrick Li [email protected]:

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

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

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

2008/9/4 Patrick Li [email protected]:

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

Hi –

On Thu, 4 Sep 2008, 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.

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 Aug 31, 2008, at 8:35 PM, Patrick Li wrote:

around this, which creates some scoping problems.
http://drawohara.com/post/48758159/ruby-temporary-methods-for-dsls

a @ http://codeforpeople.com/

Hi,

In message “Re: Request for Block local methods, and Proc syntax”
on Mon, 1 Sep 2008 11:35:56 +0900, Patrick Li
[email protected] writes:

|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.

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

sure you can:

require ‘rubygems’
require ‘tagz’
include Tagz.globally

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

puts @code

puts content

cfp:~ > ruby a.rb
42

42

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
“#{ block.call }”
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)
“#{ content }”
ensure
Html::Methods.pop self
end

require ‘yaml’
}

cfp:~ > ruby a.rb

@code”: 42
content: 42

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

cheers

a @ http://codeforpeople.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

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.

Hi,

In message “Re: Request for Block local methods, and Proc syntax”
on Sun, 7 Sep 2008 01:08:01 +0900, Patrick Li
[email protected] 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.

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

Hi –

On Sun, 7 Sep 2008, Patrick Li wrote:

listener.listenTo(:playerKilledEvent) do

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

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs