Forum: Ruby Lame question about instance variable and attribute

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
dkmd_nielsen (Guest)
on 2008-10-15 18:45
(Received via mailing list)
Assuming an attribute :field is defined, is there a processing
difference between using @field and self.field [within the defining
class?]  Does the ruby interpretter take a different path in yielding
the value depending how it is referenced?  I haven't notice anything.
I'm just curious if the interpretter takes extra steps when yielding
self.field.

Thanks
Jesús Gabriel y Galán (Guest)
on 2008-10-15 18:56
(Received via mailing list)
On Wed, Oct 15, 2008 at 4:44 PM, dkmd_nielsen 
<removed_email_address@domain.invalid> wrote:
> Assuming an attribute :field is defined, is there a processing
> difference between using @field and self.field [within the defining
> class?]  Does the ruby interpretter take a different path in yielding
> the value depending how it is referenced?  I haven't notice anything.
> I'm just curious if the interpretter takes extra steps when yielding
> self.field.

@field accessed the instance variable directly, while self.field calls
the method "field" on self. So the paths are completely different:


irb(main):001:0> require 'parse_tree'
=> true
irb(main):027:0> class B
irb(main):028:1> attr_reader :b
irb(main):029:1> def test
irb(main):030:2> @b
irb(main):031:2> end
irb(main):035:1> def test3
irb(main):036:2> self.b
irb(main):037:2> end
irb(main):038:1> end
=> nil
irb(main):039:0> ParseTree.new.parse_tree_for_method(B, :test)
=> [:defn, :test, [:scope, [:block, [:args], [:ivar, :@b]]]]
irb(main):040:0> ParseTree.new.parse_tree_for_method(B, :test3)
=> [:defn, :test3, [:scope, [:block, [:args], [:call, [:self], :b]]]]

Jesus.
dkmd_nielsen (Guest)
on 2008-10-15 19:10
(Received via mailing list)
On Oct 15, 9:56 am, Jesús Gabriel y Galán <removed_email_address@domain.invalid>
wrote:
>
> irb(main):038:1> end
> => nil
> irb(main):039:0> ParseTree.new.parse_tree_for_method(B, :test)
> => [:defn, :test, [:scope, [:block, [:args], [:ivar, :@b]]]]
> irb(main):040:0> ParseTree.new.parse_tree_for_method(B, :test3)
> => [:defn, :test3, [:scope, [:block, [:args], [:call, [:self], :b]]]]
>
> Jesus.

So, in processing that involves many iterations, one should most
definitely use the instance variable reference.  Correct?

When would it be proper to use the self. reference?

Thanks, again.
David A. Black (Guest)
on 2008-10-15 19:18
(Received via mailing list)
Hi --

On Thu, 16 Oct 2008, dkmd_nielsen wrote:

>> @field accessed the instance variable directly, while self.field calls
>> irb(main):036:2> self.b
> So, in processing that involves many iterations, one should most
> definitely use the instance variable reference.  Correct?
>
> When would it be proper to use the self. reference?

The self. version is necessary if you do, or think you'll ever do, any
kind of override. In other words, if you've got:

   def name
     @name.upcase
   end

or whatever, then you'll want to use the method, unless you're doing
something even more low-level (like assigning directly to @name).


David
Thomas B. (Guest)
on 2008-10-15 19:26
dkmd_nielsen wrote:
> When would it be proper to use the self. reference?

I think never. The exception is when the setter or getter is nontrivial
(not defined by attr_reader and others), but with attr_accessors there's
no use calling the setters and getters from within the same class,
accessing the variables directly is better.

TPR.
Bryan D (Guest)
on 2008-10-15 19:45
(Received via mailing list)
On Oct 15, 7:41 am, dkmd_nielsen <removed_email_address@domain.invalid> wrote:
> Assuming an attribute :field is defined, is there a processing
> difference between using @field and self.field [within the defining
> class?]  Does the ruby interpretter take a different path in yielding
> the value depending how it is referenced?  I haven't notice anything.
> I'm just curious if the interpretter takes extra steps when yielding
> self.field.
>
> Thanks

In terms of speed, it's very close, but using @field is slightly
faster, at least on my system.

Rehearsal -----------------------------------------------
using self:   4.640000   2.350000   6.990000 (  7.032596)
using @:      4.550000   2.350000   6.900000 (  6.928132)
------------------------------------- total: 13.890000sec

                  user     system      total        real
using self:   4.660000   2.380000   7.040000 (  7.137048)
using @:      4.570000   2.360000   6.930000 (  7.075875)

Benchmark code:
require 'benchmark'

class Dummy
  attr_reader :foo
  def initialize
    @foo = 7983.3435
  end

  def using_self
    self.foo
  end

  def using_direct
    @foo
  end
end

n = 1000000
@d = Dummy.new
Benchmark.bmbm(7) do |x|
  x.report("using self:") { n.times do @d.using_self;   end }
  x.report("using @:")    { n.times do @d.using_direct; end }
end
dkmd_nielsen (Guest)
on 2008-10-16 00:25
(Received via mailing list)
On Oct 15, 10:40 am, Bryan D <removed_email_address@domain.invalid> wrote:
>
> using @:      4.570000   2.360000   6.930000 (  7.075875)
>   def using_self
> Benchmark.bmbm(7) do |x|
>   x.report("using self:") { n.times do @d.using_self;   end }
>   x.report("using @:")    { n.times do @d.using_direct; end }
> end

Thanks for the commentary, guys.  This is the kind of stuff that is
useful to me.  Most everything I do i very iterative.  Fortunately, if
you can call it fortunate, most of my bottlenecks have nothing to do
with Ruby.  Most of the time is I/O related stuff between servers.

Thanks again,
Happy Halloween
Brian C. (Guest)
on 2008-10-16 01:01
dkmd_nielsen wrote:
> Assuming an attribute :field is defined, is there a processing
> difference between using @field and self.field [within the defining
> class?]

Remember that you don't have to write "self.field" - "field" by itself
is fine, as long as you haven't assigned to a local variable called
"field" within the calling method.

def field
  123
end

puts field       # 123
field = 999
puts field       # 999
puts field()     # 123
puts self.field  # 123
This topic is locked and can not be replied to.