Help regarding def wrapper

I’d like to have a def that I can scope in one go, i.e.,

class A
  scoped_def :private, :a do
    ⋮
  end
end

at least until we get decorators in Ruby. The following seems to work:

class Class
  def scoped_def scope, name, &blk
    if [:public, :protected, :private].include? scope
      define_method name, &blk
      self.send scope, name
    else
      raise ArgumentError, "illegal visibility: %s", scope
    end
  end
end

I was wondering if anyone has any comments regarding this solution.

Would it be better to put it in Object (wrapping it in a class_eval)
and, if so, why?

Thanks,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

What do you prefer about the above, versus the existing (and, IMO, slightly prettier):

class A
     private; def meth1( arg1, arg2=:foo )
         'private'
     end

     protected; def meth2( arg1, arg2='bar' )
         'protected'
     end

     public; def meth2( arg1, arg2 )
         'public'
     end
end

With your technique, you cannot declare default values for arguments, correct? (At least, not in blocks in 1.8)

And while the above syntax that I wrote is close to yours, I further personally prefer using the public/protected/private items as they were intended, to denote blocks of methods in my class which are each, visually grouping like-scoped methods.

class A
     def public1; ...; end
     def public2; ...; end

     protected
         def protected1; ...; end
         def protected2; ...; end

     private
         def private1; ...; end
         def private2; ...; end
end

That simply makes more sense, to me personally.

···

On May 17, 2005, at 7:52 AM, Nikolai Weibull wrote:

I’d like to have a def that I can scope in one go, i.e.,

class A
  scoped_def :private, :a do
    ⋮
  end
end

Nikolai Weibull wrote:

I’d like to have a def that I can scope in one go, i.e.,

class A
  scoped_def :private, :a do
    ⋮
  end
end

I was wondering if anyone has any comments regarding this solution.

Not the best naming choice, scope != accessability.

···

--
Glenn Parker | glenn.parker-AT-comcast.net | <http://www.tetrafoil.com/&gt;

Hello Nikolai,

I was wondering if anyone has any comments regarding this solution.

I find it quite ugly. But before i write more comments can you tell me
what is the benefit you want to get from it.

If i didn't miss something fundamental i would highly recommend to use
Gavin Kistner's solution instead to invent something new for the same
purpose - hey we are using Ruby and not Perl.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

[Nikolai Weibull <mailing-lists.ruby-talk@rawuncut.elitemail.org>, 2005-05-17 15.52 CEST]

I’d like to have a def that I can scope in one go, i.e.,

class A
  scoped_def :private, :a do
    ⋮
  end
end

at least until we get decorators in Ruby. The following seems to work:

[...]

How about something like this? It's closer to the current usage:

class Class
  def method_added m
    if @decorator
      send(@decorator, m)
    end
    @decorator = nil
  end
  
  def priv
    @decorator = :private
  end
end

class C
  priv; def a() puts "private" end
  def b() puts "public" end
end

c = C.new
c.b
c.a

Gavin Kistner schrieb:

I’d like to have a def that I can scope in one go, i.e.,

With your technique, you cannot declare default values for arguments, correct? (At least, not in blocks in 1.8)

Adding to Gavin's answer, note the following difference:

   class A
     a = 5
     scoped_def :public, :m1 do a rescue $! end
     def m2() a rescue $! end
   end

   p A.new.m1 # => 5
   p A.new.m2 # => #<NameError: undefined local variable or method `a'>

Regards,
Pit

···

On May 17, 2005, at 7:52 AM, Nikolai Weibull wrote:

Gavin Kistner wrote:

> I’d like to have a def that I can scope in one go, i.e.,
>
> class A
> scoped_def :private, :a do
> ⋮
> end
> end

What do you prefer about the above, versus the existing (and, IMO,
slightly prettier):

class A
    private; def meth1( arg1, arg2=:foo )
        'private'
    end

    protected; def meth2( arg1, arg2='bar' )
        'protected'
    end

    public; def meth2( arg1, arg2 )
        'public'
    end
end

Well, the visibility will affect all methods defined after it and I
really want to intermingle methods of varying visibility, i.e., not, as
you suggest below, to group them by visibility.

With your technique, you cannot declare default values for arguments,
correct? (At least, not in blocks in 1.8)

And while the above syntax that I wrote is close to yours, I further
personally prefer using the public/protected/private items as they
were intended, to denote blocks of methods in my class which are
each, visually grouping like-scoped methods.

Actually, I’d argue that this isn’t how they were intended, as that is a
behavior that these methods take upon themselves if not passed any
arguments. Looking at the standard library, there are thirty instances
of private being used as below and ninety-one instances of the

  private :name1, :name2, …

kind.

class A
    def public1; ...; end
    def public2; ...; end

    protected
        def protected1; ...; end
        def protected2; ...; end

    private
        def private1; ...; end
        def private2; ...; end
end

Anyway, thanks for your input,
        nikolai

···

On May 17, 2005, at 7:52 AM, Nikolai Weibull wrote:

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Glenn Parker wrote:

Nikolai Weibull wrote:

> I’d like to have a def that I can scope in one go, i.e.,
>
> class A
> scoped_def :private, :a do
> ⋮
> end
> end
>
> I was wondering if anyone has any comments regarding this solution.

Not the best naming choice, scope != accessability.

No, but scope has to do with visibility/accessability in a sense. It’s
shorter than the only alternative I can think of off the top of my head,
namely “restricted_def”,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Lothar Scholz wrote:

> I was wondering if anyone has any comments regarding this solution.

I find it quite ugly. But before i write more comments can you tell me
what is the benefit you want to get from it.

If i didn't miss something fundamental i would highly recommend to use
Gavin Kistner's solution instead to invent something new for the same
purpose - hey we are using Ruby and not Perl.

As I said in my reply to Gavin’s solution, the idea is that I want to
combine visibility with definition. Gavin’s way doesn’t work the way
that his suggestion may imply (which makes it somewhat dangerous) and
isn’t really an option in my case. I mainly want to save having to
write

  def m
    ⋮
  end

  private :m

and instead combine the two. The reason for this is that I’m writing
code that’s going to be included in a manuscript and I was trying to
keep things short and simple. I guess this wasn’t as simple as I had
hoped…,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Carlos wrote:

[Nikolai Weibull …]

> I’d like to have a def that I can scope in one go, i.e.,
>
> class A
> scoped_def :private, :a do
> ⋮
> end
> end
>

How about something like this? It's closer to the current usage:

class Class
  def method_added m
    if @decorator
      send(@decorator, m)
    end
    @decorator = nil
  end
  
  def priv
    @decorator = :private
  end
end

class C
  priv; def a() puts "private" end
  def b() puts "public" end
end

c = C.new
c.b
c.a

Hehe, that’s kind of sweet actually. Thanks,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Nikolai Weibull wrote:

Glenn Parker wrote:

Not the best naming choice, scope != accessability.

No, but scope has to do with visibility/accessability in a sense. It’s
shorter than the only alternative I can think of off the top of my head,
namely “restricted_def”,

How about "def_access"? I suggest keeping "def" at the start (for syntax-aware editors), but I wouldn't use this anyway.

···

--
Glenn Parker | glenn.parker-AT-comcast.net | <http://www.tetrafoil.com/&gt;

Hello Nikolai,

and instead combine the two. The reason for this is that I’m writing
code that’s going to be included in a manuscript and I was trying to
keep things short and simple. I guess this wasn’t as simple as I had
hoped…,

When writing a manuscript do you really think it is more readable if
you use your own syntax workaround.

I didn't follow the RCR (i think it was rejected due to implementation
complexity) that suggested that 'def' returns the defined symbol so
that we could write:

public def foo
end

At this time my argument against this was also that public (and
everything else) should have just one clear and precise meaning and
usage. With this it would increase 'public' to three different use
cases which is IMHO bad for readability.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

Nikolai Weibull schrieb:

Gavin Kistner wrote:

What do you prefer about the above, versus the existing (and, IMO, slightly prettier):

class A
   private; def meth1( arg1, arg2=:foo )
       'private'
   end
end

Well, the visibility will affect all methods defined after it and I
really want to intermingle methods of varying visibility, i.e., not, as
you suggest below, to group them by visibility.

But you *can* use Gavin's syntax, if you "decorate" *every* method with its visibility. The sequence doesn't matter at all in this case.

Regards,
Pit

I suppose I assumed that you were always going to be specifying the 'scope' of each method you defined, in which case the new private/protected/public keyword for that particular def would take over. You're correct that what I suggested would be quite dangerous (or at least ripe for a confusing bug) if intermingled with standard def methods.

It would be nice if the def 'method' returned a symbol with the name of the method, in which case:

private def foo; ...; end

would work as a this-method-only specification.

···

On May 17, 2005, at 9:51 AM, Nikolai Weibull wrote:

class A
scoped_def :private, :a do
   ⋮
end
end

What do you prefer about the above, versus the existing (and, IMO,
slightly prettier):

class A
    private; def meth1( arg1, arg2=:foo )
        'private'
    end

    protected; def meth2( arg1, arg2='bar' )
        'protected'
    end

Well, the visibility will affect all methods defined after it and I
really want to intermingle methods of varying visibility, i.e., not, as
you suggest below, to group them by visibility.

Glenn Parker wrote:

Nikolai Weibull wrote:
> Glenn Parker wrote:
>
> > Not the best naming choice, scope != accessability.
>
> No, but scope has to do with visibility/accessability in a sense. It’s
> shorter than the only alternative I can think of off the top of my head,
> namely “restricted_def”,

How about "def_access"? I suggest keeping "def" at the start (for
syntax-aware editors), but I wouldn't use this anyway.

Hm, that may work I suppose…,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Lothar Scholz wrote:

Hello Nikolai,

When writing a manuscript do you really think it is more readable if
you use your own syntax workaround.

Well, if it’s shown how it works and how it’s used, then yes. How else
would books on Lisp ever get written?

I didn't follow the RCR (i think it was rejected due to implementation
complexity) that suggested that 'def' returns the defined symbol so
that we could write:

public def foo
end

At this time my argument against this was also that public (and
everything else) should have just one clear and precise meaning and
usage. With this it would increase 'public' to three different use
cases which is IMHO bad for readability.

And now it has only has two meanings and uses, neither of which is that
great. I guess I’ll just have to wait for decorators…

By the way, I wasn’t suggesting that something like this be included in
Ruby’s standard library. It was more of an exercise in Ruby than
anything else. It also happened to allow me to write the visibility and
the method name on the same line, which is what I wanted. It’s not a
good solution, but it at least seems to work,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}

Pit Capitain wrote:

Nikolai Weibull schrieb:

> Gavin Kistner wrote:

> >What do you prefer about the above, versus the existing (and, IMO,
> >slightly prettier):
> >
> >class A
> > private; def meth1( arg1, arg2=:foo )
> > 'private'
> > end
> >end

> Well, the visibility will affect all methods defined after it and I
> really want to intermingle methods of varying visibility, i.e., not, as
> you suggest below, to group them by visibility.

But you *can* use Gavin's syntax, if you "decorate" *every* method with
its visibility. The sequence doesn't matter at all in this case.

Yes, but that’s an unfortunate consequence that I’m not willing to live
with. Anyway, since there were such strong opinions against my
suggested “‘syntax’-patch”, I have changed my mind and will simply write
out the necessary

  private :name1, :name2, …

lines.

Thanks,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}