Why private #binding?

Why is #binding a private method? I end up doing a lot of this:

class Scope
def binding
binding
end
end

In order to setup a scope for ERB evaluation, among other uses.

On Thu, Jun 10, 2010 at 12:38 AM, Intransition [email protected]
wrote:

Why is #binding a private method? I end up doing a lot of this:

class Scope
def binding
binding
end
end

In order to setup a scope for ERB evaluation, among other uses.

I can think of two potential reasons.

  1. Because binding exposes the internals of the receiver.

  2. because if it were public then in a case like:

class A
def self.binding_of(b)
b.binding
end
end

A.binding_of(“abc”)

might well return a binding with self == A, rather than the string,
because binding returns the bindings “at the point of call”


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Hi,

In message “Re: Why private #binding?”
on Thu, 10 Jun 2010 22:29:32 +0900, Rick DeNatale
[email protected] writes:

|I can think of two potential reasons.
|
|1. Because binding exposes the internals of the receiver.
|
|2. because if it were public then in a case like:
|
|
|class A
| def self.binding_of(b)
| b.binding
| end
|end
|
|A.binding_of(“abc”)
|
|might well return a binding with self == A, rather than the string,
|because binding returns the bindings “at the point of call”

The latter one was the biggest reason for me.

          matz.

On Jun 10, 1:01 pm, Yukihiro M. [email protected] wrote:

|
|because binding returns the bindings “at the point of call”

The latter one was the biggest reason for me.

It doesn’t recognize it’s receiver?

Hi,

In message “Re: Why private #binding?”
on Fri, 11 Jun 2010 04:57:32 +0900, Intransition
[email protected] writes:

|It doesn’t recognize it’s receiver?

binding returns the binding object that has info on

  • the receiver
  • local variables
  • etc.

but invoking it from public form does not explain the context except
for the receiver.

          matz.

On Thu, Jun 10, 2010 at 1:01 PM, Yukihiro M. [email protected]
wrote:

|
|because binding returns the bindings “at the point of call”

The latter one was the biggest reason for me.

Knowing you, I suspected that that was the case. It would be for me as
well.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

On Thu, Jun 10, 2010 at 5:08 PM, Yukihiro M. [email protected]
wrote:

  • local variables
  • etc.

but invoking it from public form does not explain the context except
for the receiver.

                                                   matz.

Yes, actually my initial thought about self was the only thing that a
non-private binding method would get ‘right’.

The real issue, I think, is that objects in general don’t have
bindings, invocations do. Making Kernel#binding private means that
unless you resort to trickery, it will only occur in the context of an
invocation.

Here’s a better example:

def test(code)
x = 1
b = “abc”.send(:binding)
eval(code, b)
end

test(“self”) # => “abc”
test(“x”) # => 1

The variable x has nothing to do with the string “abc”.

“abc”.instance_eval is a better choice if you want to bind self in an
evaluated string or block.

Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Hi,

In message “Re: Why private #binding?”
on Fri, 11 Jun 2010 08:25:28 +0900, Intransition
[email protected] writes:

|But ERB needs a binding. And in almost every use of binding I have
|ever had it eds up coming from an external object. After all, it is
|rare one would need to use the binding from within the binding. I will
|often I make quick use of such a binding --form the place that it is
|created, but in the end I almost always move it to a separate scope so
|that I can strictly control what the eval sees.

Probably you want something different from binding, maybe restricted
eval environment, do you?

          matz.

On Jun 10, 6:45 pm, Rick DeNatale [email protected] wrote:

  • the receiver

eval(code, b)
end

test(“self”) # => “abc”
test(“x”) # => 1

The variable x has nothing to do with the string “abc”.

“abc”.instance_eval is a better choice if you want to bind self in an
evaluated string or block.

But ERB needs a binding. And in almost every use of binding I have
ever had it eds up coming from an external object. After all, it is
rare one would need to use the binding from within the binding. I will
often I make quick use of such a binding --form the place that it is
created, but in the end I almost always move it to a separate scope so
that I can strictly control what the eval sees.

So I understand technically what you and matz are saying, but from a
practical point a view I think #binding would be most useful if it was
defined as something akin to:

def binding(locals={})
locals.each{|k,v| local_varaible_set(k,v) }
return binding
end

Such that if binding is called without an explicit receiver, it
behaves at it does now, but with one as above. As it stands no one
every uses binding with a receiver b/c it’s meaningless.

On Jun 10, 8:25 pm, Yukihiro M. [email protected] wrote:

Probably you want something different from binding, maybe restricted
eval environment, do you?

Is it truly different? How does one get restricted eval environment
without binding?

On Thu, Jun 10, 2010 at 7:25 PM, Intransition [email protected]
wrote:

On Jun 10, 6:45 pm, Rick DeNatale [email protected] wrote:

that I can strictly control what the eval sees.
I have to admit that you totally lost me in that last sentence, and
why it supports the argument to make Kernel#binding public.

So I understand technically what you and matz are saying, but from a
practical point a view I think #binding would be most useful if it was
defined as something akin to:

def binding(locals={})
locals.each{|k,v| local_varaible_set(k,v) }
return binding
end

So what’s so sacred about the method name, why not just take that idea
and add (not to standard Ruby but yourself)

module Kernel
def to_binding(locals={})
locals.each{|k,v| local_variable_set(k,v) }
return binding
end
end

or, following Matz’ observation a better name might be
to_eval_environment


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Hi,

In message “Re: Why private #binding?”
on Fri, 11 Jun 2010 11:27:19 +0900, Intransition
[email protected] writes:

|> Probably you want something different from binding, maybe restricted
|> eval environment, do you?
|
|Is it truly different? How does one get restricted eval environment
|without binding?

At least, you don’t want some part of the current binding attributes.
You are free to use binding to implement restricted eval environment,
but if you want to change the binding behavior, it’s different story.
Right now, I don’t feel making it public is worth changing, when you
can define a small function to create binding for restricted
environment.

          matz.

On Fri, Jun 11, 2010 at 4:32 AM, Yukihiro M. [email protected]
wrote:

At least, you don’t want some part of the current binding attributes.
You are free to use binding to implement restricted eval environment,
but if you want to change the binding behavior, it’s different story.
Right now, I don’t feel making it public is worth changing, when you
can define a small function to create binding for restricted
environment.

Which is what I suggested. That’s the beauty of Ruby, a programmer can
extend it without having to change it for the rest of us.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale