Foo= ... the only exception to the implicit-self rule?

Sorry to ask this again, but...

*why* does

  foo
seems to always means
  self.foo

except that
  foo= ...
means
  local variable foo = ...
and not
  self.foo=

I find this keeps breaking up an otherwise uniform style in code, and almost
leads me towards abandoning #foo=(value) as a setter, and using #foo(value)
instead (with some distinguished sentinel value to distinguish getter from
setter, which I hate!)

I know that otherwise one would somehow have to indicate local variables.
Was this the main reason for this choice?

Does this issue (distinguishing local variables) have to be dealt with
anyway in any other contexts e.g. block-local variables?

Thanks.

Hi,

I know that otherwise one would somehow have to indicate local variables.
Was this the main reason for this choice?

Yes.

Does this issue (distinguishing local variables) have to be dealt with
anyway in any other contexts e.g. block-local variables?

Yes.

              matz.

···

In message "Re: foo= ... the only exception to the implicit-self rule ?" on Thu, 6 Oct 2005 13:16:49 +0900, "itsme213" <itsme213@hotmail.com> writes:

itsme213 wrote:

Sorry to ask this again, but...

*why* does

  foo
seems to always means
  self.foo

except that
  foo= ...
means
  local variable foo = ...
and not
  self.foo=

I find this keeps breaking up an otherwise uniform style in code, and almost
leads me towards abandoning #foo=(value) as a setter, and using #foo(value)
instead (with some distinguished sentinel value to distinguish getter from
setter, which I hate!)

I agree and ten not to use them for this reason. I suspect most others
feel the same. One nice way to create a "setter" is:

  def foo(val=NilClass)
    unless val == NilClass
      @foo = val
    end
    @foo
  end

  foo #=> nil
  foo(10)
  foo #=> 10

Facets has this by the way (in next release):

  require 'facet/kernel/attr_setter'

  attr_setter :foo

I know that otherwise one would somehow have to indicate local variables.
Was this the main reason for this choice?

Yes. I think it was considered simply too "dangerous" to give setter
methods precedence. I'm not sure why since there tend to be quite few
of them, but I can see how it might catch one by suprise if their was a
setter defined that one didn't know about.

Some have suggested allowing a prefixed dot to mean 'self.', which
would help a little. Eg.

  .foo=

But all other suggestions I can recall seem just as bad as having to
use 'self.'

Does this issue (distinguishing local variables) have to be dealt with
anyway in any other contexts e.g. block-local variables?

Do you mean defining vars local to a block? Perhaps?

   { x := 1 }

I can only imagine it has been suggested before though.

T.

itsme213 wrote:
...

I find this keeps breaking up an otherwise uniform style in code, and almost
leads me towards abandoning #foo=(value) as a setter, and using #foo(value)
instead (with some distinguished sentinel value to distinguish getter from
setter, which I hate!)

You can avoid the sentinal (at a small cost):

def foo(*args)
  case args.size
  when 1
    @foo = args[0]
  when 0
    @foo
  else raise ArgumentError, "Too many args, #{args.size}"
  end
end

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Thanks Matz.

"Yukihiro Matsumoto" <matz@ruby-lang.org> wrote in message

>Does this issue (distinguishing local variables) have to be dealt with
>anyway in any other contexts e.g. block-local variables?

Yes.

Have you decided whether 2.0 will require all local vars to be distinguished
via some syntax (e.g. |...|), or will 2.0 continue the current special-case
handling for self.foo= ?

True.

However, the bigger issue is that writer and reader are now embedded in a
single method, and its impossible to do things like extend the writer to do
notifications and the like.

I guess a set_x(val) is the other alternative. Not sure which I dislike more
:frowning:

"Joel VanderWerf" <vjoel@path.berkeley.edu> wrote in message
news:4344B6AC.7070400@path.berkeley.edu...

itsme213 wrote:
..
> I find this keeps breaking up an otherwise uniform style in code, and

almost

> leads me towards abandoning #foo=(value) as a setter, and using

#foo(value)

> instead (with some distinguished sentinel value to distinguish getter

from

···

> setter, which I hate!)

You can avoid the sentinal (at a small cost):

def foo(*args)
  case args.size
  when 1
    @foo = args[0]
  when 0
    @foo
  else raise ArgumentError, "Too many args, #{args.size}"
  end
end

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Yukihiro Matsumoto wrote:

Hi,

>I know that otherwise one would somehow have to indicate local variables.
>Was this the main reason for this choice?

Yes.

I'm not sure local precedence is worth it though. Consider:

  require 'yaml'
  eqmeths =
  ObjectSpace.each_object{|o|
    s = o.methods.select{ |m| m.to_s =~ /=$/ }
    eqmeths |= s
  }
  y eqmeths

···

In message "Re: foo= ... the only exception to the implicit-self rule ?" > on Thu, 6 Oct 2005 13:16:49 +0900, "itsme213" <itsme213@hotmail.com> writes:

  ---
  - "="
  - "=="
  - "==="
  - ">="
  - "<="
  - ui=
  - debug=
  - sync=
  - lineno=
  - pos=
  - default=
  - ssl_available=
  - uid=
  - euid=
  - gid=
  - egid=
  - groups=
  - maxgroups=
  - abort_on_exception=
  - priority=
  - critical=
  - families=
  - private_types=
  - anchors=
  - bufsize=
  - version=
  - verify_data=
  - only_signed=
  - verify_signer=
  - verify_chain=
  - verify_root=
  - only_trusted=

T.

Hi,

···

In message "Re: foo= ... the only exception to the implicit-self rule ?" on Thu, 6 Oct 2005 14:36:48 +0900, "itsme213" <itsme213@hotmail.com> writes:

Have you decided whether 2.0 will require all local vars to be distinguished
via some syntax (e.g. |...|), or will 2.0 continue the current special-case
handling for self.foo= ?

I have never planned for any kind of explicit local variable
declaration. So the latter would be an answer.

              matz.

I'm amazed that you find either the above or foo(x) more appealing than simply using self.foo = x. In my personal opinion, the assignment is clear, and made clearer by the presence of 'self'.

The only alternative that I would ever (personally) endorse would be some sort of sigil for local variables like there is for global, instance, and class variables. (Ick, more punctuation. Ick, more typying. Ick, breaks backwards compatibility. But: at least it would be consistent with other variables.) Something like:
%foo = 12 #The randomly-chosen % means local variable.
foo = 12 #Method call with implicit self.

But...really, I'm reasonably happy with the way things are now.

···

On Oct 6, 2005, at 1:31 AM, itsme213 wrote:

I guess a set_x(val) is the other alternative. Not sure which I dislike more
:frowning:

This would really make ruby ugly. One of the beauties about
ruby is that you don't have to declare your variables (type or
existance). There are currently deficiencies in the
flexibility of variable scoping (only def/class/module can make
real local variables as far as I know), but I would hope that
could be solved without adding variable declarations.

Take a look at my RCR 307. In this one, you can do this:

obj.foo(arg1,arg2) = value

which would be equivalent to:

obj.send(:foo=,arg1,arg2,value)

Well, there is no reason this RCR couldn't handle the no
receiver case:

foo(arg1,arg2) = value

And the no receiver/no arg case:

foo() = value

which would be equivalent to:

self.foo = value

Just like the case when you already are using a local variable
"foo" where you use "foo()" to call the method foo, the same
can be done for assignment.

But, I think the self.foo=value syntax would still be preferred
by most. I'm not sure why you dislike it so much to propose
making such radical changes.

We are also talking about inside the class, so you know the
implementation. Unless foo= is complex, you might want to just
inline it whenever you want to use it (typically @foo=value).
This will give you a performance boost since you are cutting
out a method call (runtime is probably dominated by the method
call mechanism in most cases).

···

--- itsme213 <itsme213@hotmail.com> wrote:

Have you decided whether 2.0 will require all local vars to
be distinguished
via some syntax (e.g. |...|), or will 2.0 continue the
current special-case
handling for self.foo= ?

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005

Hi --

···

On Fri, 7 Oct 2005, Trans wrote:

Yukihiro Matsumoto wrote:

Hi,

In message "Re: foo= ... the only exception to the implicit-self rule ?" >> on Thu, 6 Oct 2005 13:16:49 +0900, "itsme213" <itsme213@hotmail.com> writes:

>I know that otherwise one would somehow have to indicate local variables.
>Was this the main reason for this choice?

Yes.

I'm not sure local precedence is worth it though. Consider:

require 'yaml'
eqmeths =
ObjectSpace.each_object{|o|
   s = o.methods.select{ |m| m.to_s =~ /=$/ }
   eqmeths |= s
}
y eqmeths

---
- "="
- "=="
- "==="
- ">="
- "<="
- ui=
- debug=
- sync=
- lineno=
- pos=
- default=
- ssl_available=
- uid=
- euid=
- gid=
- egid=
- groups=
- maxgroups=
- abort_on_exception=
- priority=
- critical=
- families=
- private_types=
- anchors=
- bufsize=
- version=
- verify_data=
- only_signed=
- verify_signer=
- verify_chain=
- verify_root=
- only_trusted=

Can you explain what you mean? I'm not getting it.

David

--
David A. Black
dblack@wobblini.net

I guess a set_x(val) is the other alternative. Not sure which I dislike more
:frowning:

I'm amazed that you find either the above or foo(x) more appealing than simply using self.foo = x. In my personal opinion, the assignment is clear, and made clearer by the presence of 'self'.

[snip]

But...really, I'm reasonably happy with the way things are now.

I believe I have only ever run into this problem when using instance_eval(). Is it more pervasive than that?

With instance_eval() it could be argued that I'm already making questionable choices, and this is just punishment, I think. :wink:

James Edward Gray II

···

On Oct 6, 2005, at 8:51 AM, Gavin Kistner wrote:

On Oct 6, 2005, at 1:31 AM, itsme213 wrote:

I guess a set_x(val) is the other alternative. Not sure which I dislike more
:frowning:

I'm amazed that you find either the above or foo(x) more appealing than simply using self.foo = x. In my personal opinion, the assignment is clear, and made clearer by the presence of 'self'.

it's just my opinion, but i think this is clear as a whistle:

   require 'traits'

   class Widget
     traits %w( colour width height style )
   end

   class Button < Widget
     color 'blue'
     width 42
     height 42
     sytle 'swirly'
   end

and this

   require 'traits'

   class C
     traits(TRAITS = %w( a b c d e f ))

     def initialize *args
       TRAITS.each{|t| send t, args.shift}
     end
   end

visually the reader/writer method (writer if given arg) can be very, very nice
on the eyes and fingers - i just takes getting used to, like dropping the ';'
and '$' when moving from perl to ruby. :wink:

i espcially like that i can do

   def init hash = {}
     hash.each{|k,v| send k, v}
   end

instead of

   def init hash = {}
     hash.each do |k,v|
       meth = "#{ k }="
       send meth, v
     end
   end

which always feels hackish to me

The only alternative that I would ever (personally) endorse would be some
sort of sigil for local variables like there is for global, instance, and
class variables. (Ick, more punctuation. Ick, more typying. Ick, breaks
backwards compatibility. But: at least it would be consistent with other
variables.) Something like: %foo = 12 #The randomly-chosen % means local
variable. foo = 12 #Method call with implicit self.

i think a symbol for local vars makes a TON of sense and is, really, in
keeping with ruby's design since every other scope is signaled by a symbol.

the rule could be

   foo = 42

   # if method exists foo=, use it
   # else local var

   foo := 42 # force local var

or

   !foo = 42 # force local var
   %foo = 42 # force local var

the thing with local vars is that, if ruby ALSO changed to lookup to search
for methods FIRST, and then to fall back on local you really wouldn't have to
use the local symbol/marker exectp in cases where a local var shadows a
method in the scope of object instance.

But...really, I'm reasonably happy with the way things are now.

me too.

cheers.

-a

···

On Thu, 6 Oct 2005, Gavin Kistner wrote:

On Oct 6, 2005, at 1:31 AM, itsme213 wrote:

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

Can you explain what you mean? I'm not getting it.

Sure. Simply that there are very few setter methods built-in to Ruby.
On top of which almost all are particular to very special contexts. So
there's very little chance of surprise if setter methods were in fact
to have precendence over locals. -- In other words, one would know
every setter and thus know to avoid using it.

OTOH, I suppose it might present some issues with dynamic methods.

Here's another list by Class/Module instance_method. Between this list
and the prior I think that all of them --and there's quite a bit of
overlap.

  require 'yaml'

  eqmeths = {}
  [Module,Class].each { |mod|
    ObjectSpace.each_object(mod) { |c|
      s =
      s |= c.public_instance_methods(false).select{ |m| m.to_s =~ /=$/
}
      s |= c.private_instance_methods(false).select{ |m| m.to_s =~ /=$/
}
      s |= c.protected_instance_methods(false).select{ |m| m.to_s =~
/=$/ }
      s.reject!{ |e| e !~ /\w/ }
      eqmeths[c.name] = s unless s.empty?
    }
  }
  puts
  y eqmeths

···

---
YAML::PrivateType:
  - type_id=
  - value=
YAML::SpecialHash:
  - default=
YAML::Syck::BadAlias:
  - name=
YAML::BaseEmitter:
  - options=
YAML::Stream:
  - documents=
  - options=
Process::GID:
  - eid=
YAML::Syck::PrivateType:
  - type_id=
  - value=
YAML::Syck::DomainType:
  - type_id=
  - value=
  - domain=
YAML::YPath:
  - segments=
  - flags=
  - predicates=
Dir:
  - pos=
YAML::Syck::Parser:
  - options=
Thread:
  - priority=
  - abort_on_exception=
Hash:
  - default=
Process:
  - gid=
  - egid=
  - uid=
  - maxgroups=
  - euid=
  - groups=
Struct::Tms:
  - stime=
  - utime=
  - cstime=
  - cutime=
Process::UID:
  - eid=
YAML::DomainType:
  - type_id=
  - value=
  - domain=
YAML::Syck::Node:
  - type_id=
  - value=
  - anchor=
  - kind=
IO:
  - lineno=
  - sync=
  - pos=
YAML::Syck::Loader:
  - bufsize=
  - private_types=
  - families=
  - anchors=

T.

"Eric Mahurin" <eric_mahurin@yahoo.com> wrote in message

But, I think the self.foo=value syntax would still be preferred
by most. I'm not sure why you dislike it so much to propose
making such radical changes.

I would be happy if all self calls required self.foo, or if self was
uniformly optional.

It's just that
   bar
   baz
   self.foo=
   foo

leaves the third line sticking out to me. Perhaps very much about personal
preference.

We are also talking about inside the class, so you know the

It affects other places as well, such as instance_eval.

p.s. I didn't mean to gripe, I love the language :slight_smile:

Hi --

···

On Thu, 6 Oct 2005, James Edward Gray II wrote:

On Oct 6, 2005, at 8:51 AM, Gavin Kistner wrote:

On Oct 6, 2005, at 1:31 AM, itsme213 wrote:

I guess a set_x(val) is the other alternative. Not sure which I dislike more
:frowning:

I'm amazed that you find either the above or foo(x) more appealing than simply using self.foo = x. In my personal opinion, the assignment is clear, and made clearer by the presence of 'self'.

[snip]

But...really, I'm reasonably happy with the way things are now.

I believe I have only ever run into this problem when using instance_eval(). Is it more pervasive than that?

It's always the case that

   bareword = <anything>

is parsed as a local variable assignment, not a method call. It's
really not a big deal, though -- it's a small price to pay for all the
times we don't have to use an explicit 'self' receiver.

David

--
David A. Black
dblack@wobblini.net

Hi --

i think a symbol for local vars makes a TON of sense and is, really, in
keeping with ruby's design since every other scope is signaled by a symbol.

That ("in keeping with Ruby's design") is only true if you assume that
the non-local variables somehow represent the truth about Ruby's
design in a way that the local ones do not. I would suggest, however,
that the "bareword" nature of local variables is 100% as much part of
Ruby's design as the $var nature of globals, etc., is.

The thing is, it doesn't have to be a "winner-take-all" contest
between two abstractions (with symbol/without symbol). It's a system;
it can have components that differ from each other, and/or are similar
to each other, in any number of ways.

David

···

On Thu, 6 Oct 2005, Ara.T.Howard wrote:

--
David A. Black
dblack@wobblini.net

"Ara.T.Howard" <Ara.T.Howard@noaa.gov> wrote in message

news:Pine.LNX.4.62.0510060818160.2730@harp.ngdc.noaa.gov...

it's just my opinion, but i think this is clear as a whistle:

     color 'blue'
     width 42

It is clear. But by munging writer and reader into a single method, it makes
some kinds of manipulations of the methods difficult (e.g. programatically
generating synchronization based on readers and writers).

Using instance_eval breaks encapsulation anyways (you have full
access), so I don't see much differnce from self.foo= and
@foo=.

Personally, I think using instance_eval regularly is bad
practice since it breaks encapsulation. My guess is that many
times it is done so that some code doesn't have a specify a
receiver:

foo.bar {
  abc(1,2,3)
  xyz(4,5,6)
}

where #bar did an instance eval on the block using some object
in foo (including foo itself). I'd say this is better:

foo.bar { |o|
  o.abc(1,2,3)
  o.xyz(4,5,6)
}

where #bar simply yielded the object in foo to the block.

A little more typing, but you don't break encapsulation and you
don't have to question what "self" is in your blocks.

···

--- itsme213 <itsme213@hotmail.com> wrote:

> We are also talking about inside the class, so you know the

It affects other places as well, such as instance_eval.

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005

You're right, of course.

I was thinking of how Ruby cleverly distinguishes local variables from method calls (described on page 329 of the Pickaxe2) and confused myself. Sorry for the noise.

James Edward Gray II

···

On Oct 6, 2005, at 9:20 AM, David A. Black wrote:

It's always the case that

  bareword = <anything>

is parsed as a local variable assignment, not a method call.