Python to Ruby: Two puzzlements

I'm afraid that I'm coming from Python, a B&D language where I'm used to
everything be spelled out cleanly, and although I programmed in Perl for
many years that was also many years ago. Ruby is baffling the heck out
of me.

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined? It's just hanging there in space. In the same
breath, what does the 'super' keyword do in the append_features()
method, and why does it need a 'self' in front of it? I've tried
reading ruby-docs without finding much illumination.

module Mix
   def inst_meth
     puts 'inst_meth'
   end

   module ClassMethods
     def class_meth
       puts 'class_meth'
     end
   end

   extend ClassMethods

   def self.append_features(klass)
     super
     klass.extend(ClassMethods)
   end
end

Second, I've seen the following constructions:

validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i

        and

check_associations %w(friends downloads links)

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
well?), but I can't find documentation to that effect inside the
references available on-line. (And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

        Thanks!

                Elf

I'm afraid that I'm coming from Python, a B&D language where I'm used
to everything be spelled out cleanly, and although I programmed in
Perl for many years that was also many years ago. Ruby is baffling
the heck out of me.

I've been looking at two examples, and I was wondering if someone
could explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined?

It's defined in Class:

Class.methods.grep /ext/

=> ["extend"]

It's just hanging there in space.

Well, if you want to call it like that... Then String and Fixnum are also hanging in space. In fact these are very basic parts of Ruby that are essentially defined in the interpreter (in C). (Btw, you can nevertheless override most of the basic stuff which makes a great part of Ruby's flexibility!)

# silly example:

s="foo"

=> "foo"

s.length

=> 3

class String
alias __length length
def length() 2 * __length end
end

=> nil

s.length

=> 6

In the same
breath, what does the 'super' keyword do in the append_features()
method,

"super" without brackets invokes the same method with the same arguments in the super class. You can also explicitely hand over arguments (or no arguments) by using brackets:

class Foo
def bar(x) puts "Foo: #{x}" end
end

=> nil

class Bar < Foo
def bar(a,b)
super(a)
puts "Bar: #{b}"
end

=> nil

Bar.new.bar 1, 2

Foo: 1
Bar: 2
=> nil

and why does it need a 'self' in front of it?

Inside the class "self" references the class itself:

class Foo
p self
end

Foo
=> nil

Whenever you see "def <obj>.<method>(...)... end" then a singleton method is defined for this instance. Only this instance has this method. If the instance happens to be a class you get roughly the same as a class method in another language.

<snip/>

Second, I've seen the following constructions:

validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i

       and

check_associations %w(friends downloads links)

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs

Right!

(does this mean there's a %qq() and %qx() as
well?),

%x{date}

=> "Wed Sep 28 20:56:11 2005\n"

single quotes

%q{aa: #{1+2}}

=> "aa: \#{1+2}"

double quotes

%Q{aa: #{1+2}}

=> "aa: 3"

Can't remember whether these are the same in Perl. Note that #{} evaluates the expression, converts it into a string via #to_s and includes it at this place; this is similar to sprintf("%s", expr).

but I can't find documentation to that effect inside the
references available on-line.

http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html#UB

(And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

Buy the Pickaxe!

:-))

It's really worth every penny.

Kind regards

    robert

···

Elf M. Sternberg <elf@drizzle.com> wrote:

%r{} is a regular expression literal (like // ) and %w() is an array
literal for string arrays: %w(foo bar baz quux) is the same as ["foo",
"bar", "baz", "quux"]

Elf M. Sternberg wrote:

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined?

It's Object#extend and ri knows about it:

---------------------------------------------------------- Object#extend
     obj.extend(module, ...) => obj ------------------------------------------------------------------------
     Adds to _obj_ the instance methods from each module given as a parameter.
                                                                                module Mod def hello "Hello from Mod.\n" end end
                                                                                class Klass def hello "Hello from Klass.\n" end end
                                                                                k = Klass.new k.hello #=> "Hello from Klass.\n" k.extend(Mod) #=> #<Klass:0x401b3bc8> k.hello #=> "Hello from Mod.\n"

what does the 'super' keyword do in the append_features()
method, and why does it need a 'self' in front of it? I've tried
reading ruby-docs without finding much illumination.

def obj.foo defines a method on an object itself. If you do def self.method in a module you define a method on the module object itself and not as an instance method of the module.

super calls the implementation of the method in a super class -- in the sample it calls Module#append_features and ri knows about it:

------------------------------------------------- Module#append_features
     append_features(mod) => mod ------------------------------------------------------------------------
     When this module is included in another, Ruby calls +append_features+ in this module, passing it the receiving module in _mod_. Ruby's default implementation is to add the constants, methods, and module variables of this module to _mod_ if this module has not already been added to _mod_ or one of its ancestors.
     See also +Module#include+.

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
well?), but I can't find documentation to that effect inside the
references available on-line.

Yup, and the Pickaxe knows about them: http://www.rubycentral.com/book/language.html#UB

(And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

Buy the Pickaxe! Or read the old one online. :wink:

The one thing that really helped me when I first started learning this a long
time ago is to make sure you understand the difference between class and
instance methods.

class Foo
  def Foo.class_m
    #this is the same as "self.class_m"
    "in class method"
  end

  def instance_m
    "in instance method"
  end
end

Foo.class_m

in class method

Foo.instance_m

NoMethodError: undefined method `instance_m' for Foo:Class

a = Foo.new

=> #<Foo:0xb7ca10b8>

a.class_m

NoMethodError: undefined method `class_m' for #<Foo:0xb7ca10b8>

a.instance_m

in instance method

It's all because "a" is of type "Foo" while "Foo" is of type "Class":

a.class

=> Foo

Foo.class

=> Class

I'm afraid that I'm coming from Python, a B&D language where I'm used to
everything be spelled out cleanly, and although I programmed in Perl for
many years that was also many years ago. Ruby is baffling the heck out
of me.

Welcome to Ruby. Hopefully it will stop baffling you very soon now. :wink:

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on.

I'll sure try.

The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined?

It is defined in Object.

It adds the instance methods from the module parameter to the object it is called on. In your example it was called with an implicit self as the target object and self was Mix. Thus the methods get added to the class itself (becoming class methods).

For what it's worth, I don't like that example very much. :wink:

In the same
breath, what does the 'super' keyword do in the append_features()
method,

super calls the overridden version of the current method. In this case, append_features() in Module itself.

and why does it need a 'self' in front of it?

That's how we define class method. The following are equivalent:

module Mix
     def Mix.append_features() end
     def self.append_features() end
end

Second, I've seen the following constructions:

validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i

You're missing a comma after :url, but I get the idea.

        and

check_associations %w(friends downloads links)

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs

Bingo.

(does this mean there's a %qq() and %qx() as
well?),

Sure:

%w{...} Array from whitespace split, spaces can be escaped to ignore
%W{...} as above, but with double quoted String subs like #{...}
%q{...} single quoted String
%Q{...} or %{...} double quoted String
%x{...} shell command

but I can't find documentation to that effect inside the
references available on-line. (And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

<laughs> Well, the Pickaxe is a great book, but we try to be helpful.

James Edward Gray II

···

On Sep 28, 2005, at 1:46 PM, Elf M. Sternberg wrote:

Then, read the Pickaxe (1st edition) online until you get paid, and can buy
the second edition. Link:

http://ruby-doc.org/docs/ProgrammingRuby/

I sat and tried to come up with explanations for everything, but I'm too
tired. I think most of your questions will be answered by reading the
sections "Classes, Objects and Variables" and "Modules."

As for extend, read this:

http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_object.html#Object.extend

There are a couple more examples that might help you get the gist of extend.
Remember, *everything* is an object, even the definitions of the classes
(they're just constants).

Ask what isn't clear after that, and I'll try again.

···

On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote:

(And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

--
Rob

I'm afraid that I'm coming from Python, a B&D language where I'm used to
everything be spelled out cleanly, and although I programmed in Perl for
many years that was also many years ago. Ruby is baffling the heck out
of me.

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there.

To start off, it is not a keyword. Rather it is a method that is found
on an instance of Module (Class is a subclass of Module -- see
Class.ancestors).

Where does that came from?

I explained where it is defined but the extend keyword is also a bit
trickier. It could be thought of as running include on the singleton
class of an object. Particular gotchas are the order in which instance
methods are looked up and called.

class A
  def foo
    p 'A'
  end
end

module M
  def foo
    p 'M'
  end
end

class B
  include M
  def foo
    p 'B'
  end
end

a = A.new
b = B.new

puts 'class'
a.foo
b.foo

puts 'extend'
a.extend M
a.foo

b.extend M
b.foo

class << a
  def foo
    p 'a'
  end
end

# another way to do the above.
def b.foo
  p 'b'
end

puts 'singleton class'
a.foo
b.foo

In what
object is it defined?

Module is where extend is. The methods are in the singleton class. You
can check this out by running at the end of the above script.

C = Class.new
c = C.new
c.extend M

class << c
  p self.ancestors
end

It's just hanging there in space. In the same
breath, what does the 'super' keyword do in the append_features()
method, and why does it need a 'self' in front of it?

ri Module#append_features will talk about how the default
implementation adds constants, methods, and module variables. To
maintain this it calls the overridden method explicitly using super.
super is an example of a magic keyword. It will pass the arguments
given to the current by default.

I've tried
reading ruby-docs without finding much illumination.

That is ok. This is what this mailing list is for. It is good to hear
that some people try before they post still though...

module Mix
   def inst_meth
     puts 'inst_meth'
   end

   module ClassMethods
     def class_meth
       puts 'class_meth'
     end
   end

   extend ClassMethods

   def self.append_features(klass)
     super
     klass.extend(ClassMethods)
   end
end

This code, from what it looks like. Takes a module and appends the
instance methods along with class methods (which usually don't
follow). I haven't run it but it seems the ClassMethods module makes
this more obvious. This is a useful technique which quite a few ruby
projects have made use of (I think rails uses this). Read the comments
on the RedHanded post has there are many other interesting
improvements that can be made.

Second, I've seen the following constructions:

validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i

%r{} or %r or %r|| etc... are just another nice way of defining
regular expressions.

        and

check_associations %w(friends downloads links)

%w just creates an array from a space delliminated list. The escaping
rules follow that of '. The other version is %W which escapes like "
does.

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
well?), but I can't find documentation to that effect inside the
references available on-line. (And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

Well, in due time... I will, however, tell you that it is worth the
money for most people.

Brian.

···

On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote:

(Wandering sorta OT) here's my list of python v ruby

http://blog.ianbicking.org/ruby-python-power.html
http://www.ruby-doc.org/RubyEyeForThePythonGuy.html
http://onestepback.org/index.cgi/Tech/Ruby/PythonAndRuby.rdoc

http://reflectivesurface.com/weblog/2004/12/19/why-rails

look at Amazon's used books. Ruby way used: $20 (well worth it, it has
a python to ruby appendix) Cheapest used copies of Pickax2 are only $2
less than new copies. This speaks well for the value of that book, I
think.

Elf M. Sternberg wrote:

···

I'm afraid that I'm coming from Python, a B&D language where I'm used to
everything be spelled out cleanly, and although I programmed in Perl for
many years that was also many years ago. Ruby is baffling the heck out
of me.

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined? It's just hanging there in space. In the same
breath, what does the 'super' keyword do in the append_features()
method, and why does it need a 'self' in front of it? I've tried
reading ruby-docs without finding much illumination.

module Mix
   def inst_meth
     puts 'inst_meth'
   end

   module ClassMethods
     def class_meth
       puts 'class_meth'
     end
   end

   extend ClassMethods

   def self.append_features(klass)
     super
     klass.extend(ClassMethods)
   end
end

Second, I've seen the following constructions:

validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i

        and

check_associations %w(friends downloads links)

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
well?), but I can't find documentation to that effect inside the
references available on-line. (And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

        Thanks!

                Elf

It's defined in Class:
>> Class.methods.grep /ext/

=> ["extend"]

Actually, I think it's defined in Kernel. Object mixes in the Kernel module.
Then Module is a subclass of Object. (And Class is a subclass of Module -
hence why it shows up there).

Caleb

A fixed error:

> I'm afraid that I'm coming from Python, a B&D language where I'm used to
> everything be spelled out cleanly, and although I programmed in Perl for
> many years that was also many years ago. Ruby is baffling the heck out
> of me.
>
> I've been looking at two examples, and I was wondering if someone could
> explain to me what the Hell is going on. The first is from
> http://redhanded.hobix.com/bits/hyperextended.html, and my question is
> about the 'extend' keyword there.

To start off, it is not a keyword. Rather it is a method that is found
on an instance of Module (Class is a subclass of Module -- see
Class.ancestors).

Scratch that. Object. Sorry.

···

On 9/28/05, Brian Mitchell <binary42@gmail.com> wrote:

On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote:

> Where does that came from?

I explained where it is defined but the extend keyword is also a bit
trickier. It could be thought of as running include on the singleton
class of an object. Particular gotchas are the order in which instance
methods are looked up and called.

class A
  def foo
    p 'A'
  end
end

module M
  def foo
    p 'M'
  end
end

class B
  include M
  def foo
    p 'B'
  end
end

a = A.new
b = B.new

puts 'class'
a.foo
b.foo

puts 'extend'
a.extend M
a.foo

b.extend M
b.foo

class << a
  def foo
    p 'a'
  end
end

# another way to do the above.
def b.foo
  p 'b'
end

puts 'singleton class'
a.foo
b.foo

> In what
> object is it defined?

Module is where extend is. The methods are in the singleton class. You
can check this out by running at the end of the above script.

C = Class.new
c = C.new
c.extend M

class << c
  p self.ancestors
end

> It's just hanging there in space. In the same
> breath, what does the 'super' keyword do in the append_features()
> method, and why does it need a 'self' in front of it?

ri Module#append_features will talk about how the default
implementation adds constants, methods, and module variables. To
maintain this it calls the overridden method explicitly using super.
super is an example of a magic keyword. It will pass the arguments
given to the current by default.

> I've tried
> reading ruby-docs without finding much illumination.
>

That is ok. This is what this mailing list is for. It is good to hear
that some people try before they post still though...

> module Mix
> def inst_meth
> puts 'inst_meth'
> end
>
> module ClassMethods
> def class_meth
> puts 'class_meth'
> end
> end
>
> extend ClassMethods
>
> def self.append_features(klass)
> super
> klass.extend(ClassMethods)
> end
> end
>

This code, from what it looks like. Takes a module and appends the
instance methods along with class methods (which usually don't
follow). I haven't run it but it seems the ClassMethods module makes
this more obvious. This is a useful technique which quite a few ruby
projects have made use of (I think rails uses this). Read the comments
on the RedHanded post has there are many other interesting
improvements that can be made.

>
> Second, I've seen the following constructions:
>
> validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i
>

%r{} or %r or %r|| etc... are just another nice way of defining
regular expressions.

> and
>
> check_associations %w(friends downloads links)
>

%w just creates an array from a space delliminated list. The escaping
rules follow that of '. The other version is %W which escapes like "
does.

> I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
> qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
> well?), but I can't find documentation to that effect inside the
> references available on-line. (And before someone says "Buy the
> Pickaxe!" I'll just say that I spent my book budget this month on the
> Rails book and any other purchases will have to wait until my next
> paycheck.)

Well, in due time... I will, however, tell you that it is worth the
money for most people.

Brian.

Florian Groß wrote:

Elf M. Sternberg wrote:

I've been looking at two examples, and I was wondering if someone could
explain to me what the Hell is going on. The first is from
http://redhanded.hobix.com/bits/hyperextended.html, and my question is
about the 'extend' keyword there. Where does that came from? In what
object is it defined?

It's Object#extend and ri knows about it:

---------------------------------------------------------- Object#extend
     obj.extend(module, ...) => obj ------------------------------------------------------------------------
     Adds to _obj_ the instance methods from each module given as a parameter.
                                                                                module Mod def hello "Hello from Mod.\n" end end
                                                                                class Klass def hello "Hello from Klass.\n" end end
                                                                                k = Klass.new k.hello #=> "Hello from Klass.\n" k.extend(Mod) #=> #<Klass:0x401b3bc8> k.hello #=> "Hello from Mod.\n"

what does the 'super' keyword do in the append_features()
method, and why does it need a 'self' in front of it? I've tried
reading ruby-docs without finding much illumination.

def obj.foo defines a method on an object itself. If you do def self.method in a module you define a method on the module object itself and not as an instance method of the module.

super calls the implementation of the method in a super class -- in the sample it calls Module#append_features and ri knows about it:

------------------------------------------------- Module#append_features
     append_features(mod) => mod ------------------------------------------------------------------------
     When this module is included in another, Ruby calls +append_features+ in this module, passing it the receiving module in _mod_. Ruby's default implementation is to add the constants, methods, and module variables of this module to _mod_ if this module has not already been added to _mod_ or one of its ancestors.
     See also +Module#include+.

I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as
well?), but I can't find documentation to that effect inside the
references available on-line.

Yup, and the Pickaxe knows about them: http://www.rubycentral.com/book/language.html#UB

(And before someone says "Buy the
Pickaxe!" I'll just say that I spent my book budget this month on the
Rails book and any other purchases will have to wait until my next
paycheck.)

Buy the Pickaxe! Or read the old one online. :wink:

Elf,

It looks like you're getting the typical onslaught of friendly and useful advice. Nice, huh?

If there's one thing that I might be able to add (unless someone else has pointed it out already), it's that you should have something called irb thrown in with your ruby installation. Between ri and irb you can do a lot of tinkering around with ruby concepts in isolation.

In fact, irb works in a very similar way to the way that the python interpreter works when invoked alone on the commend line (except that when you ask it to exit, it does, instead of dropping that silly "Use Ctrl-Z plus Return to exit." line on you.). Basically, you can fire off any ruby that you could run in a script, and so you can see firsthand the effects of any language constructs whose purpose might not be clear.

If you want to start tinkering with larger chunks of code, search this mailing list over the past week or so: there's been a discussion about whether the RDE tool from sakazuki-san ( http://homepage2.nifty.com/sakazuki/rde_e.html ) is more convenient that the code-running capabilites of SciTe (also packaged with the ruby installation, on windows anyway).

Have fun, and screw around. I've learned most of my best ruby-fu by accident...

mattD

James Edward Gray II <james@grayproductions.net> writes:

Welcome to Ruby. Hopefully it will stop baffling you very soon now. :wink:

        Thank you. One can only hope.

> The first is from
> http://redhanded.hobix.com/bits/hyperextended.html, and my question is
> about the 'extend' keyword there. Where does that came from? In what
> object is it defined?

It is defined in Object.

        I guess I'm just surprised by the implicit reference. In Python
(and Perl, to an even greater if more obscure degree) extensions like
that are quite explicit. It is not immediately obvious to me that
'extend' is a part of Object.

        It's all a matter of familiarity. I wouldn't be surprised to
see something more like self.extend(...), but the 'extend ...' just
seems rather unattached.

        For what it's worth, this is making some *very* cobwebbed
portions of my brain think, "Y'know, this looks like ObjC (circa 1996,
via Webobjects) on drugs."

> I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
> qr{} and qw{} constructs

Bingo.

        That part's easy enough. Thanks!

                Elf

···

On Sep 28, 2005, at 1:46 PM, Elf M. Sternberg wrote:

James Edward Gray II wrote:

(does this mean there's a %qq() and %qx() as
well?),

Sure:

%w{...} Array from whitespace split, spaces can be escaped to ignore
%W{...} as above, but with double quoted String subs like # {...}
%q{...} single quoted String
%Q{...} or %{...} double quoted String
%x{...} shell command

Hm, and also %s for symbols. (Rarely used, though.)

Oh, and %-a- and similar is the same as %q-a- so %() is an empty string -- probably better to be explicit and add the q, though.

The proof is in the #inspect:

  Class.method :extend
    ==>#<Method: Class(Kernel)#extend>
  Class.instance_method :extend
    ==>#<UnboundMethod: Class(Kernel)#extend>
  Kernel.instance_method :extend
    ==>#<UnboundMethod: Kernel#extend>

cheers,
Mark

···

On 9/28/05, Caleb Tennis <caleb@aei-tech.com> wrote:

> It's defined in Class:
> >> Class.methods.grep /ext/
>
> => ["extend"]

Actually, I think it's defined in Kernel. Object mixes in the Kernel module.
Then Module is a subclass of Object. (And Class is a subclass of Module -
hence why it shows up there).

Well it probably should since ruby and Objective-C have a common ancestor in Smalltalk.

···

On Sep 28, 2005, at 4:11 PM, Elf M. Sternberg wrote:

        For what it's worth, this is making some *very* cobwebbed
portions of my brain think, "Y'know, this looks like ObjC (circa 1996,
via Webobjects) on drugs."

Actually everything you do in ruby has a receiving object reference
under the covers...

if you do obj.method you are explicitly setting the receiving object
... Other wise, it's always implicitly SELF

And to mess with your brain a bit more, you can do an instance_eval
where you set self to some other object ...

class Blah
    attr_accessor: a
end

obj1 = Blah.new
obj2 = Blah.new

obj1.instance_eval do
  @a = 1
end

obj2.instance_eval do
  @a = 2
end

... remember that there are actually VERY few keywords in Ruby....
everything else is a method on some object in the system ...

when you define functions in a script outside of a class definition,
self is still there for a silent single instance of Object that wraps
everything in your script.

... once you get used to that, it's pretty happy sailing.

Welcome to Ruby ... we hope you enjoy the ride.

j.

···

On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote:

James Edward Gray II <james@grayproductions.net> writes:

> On Sep 28, 2005, at 1:46 PM, Elf M. Sternberg wrote:

> Welcome to Ruby. Hopefully it will stop baffling you very soon now. :wink:

        Thank you. One can only hope.

> > The first is from
> > http://redhanded.hobix.com/bits/hyperextended.html, and my question is
> > about the 'extend' keyword there. Where does that came from? In what
> > object is it defined?

> It is defined in Object.

        I guess I'm just surprised by the implicit reference. In Python
(and Perl, to an even greater if more obscure degree) extensions like
that are quite explicit. It is not immediately obvious to me that
'extend' is a part of Object.

        It's all a matter of familiarity. I wouldn't be surprised to
see something more like self.extend(...), but the 'extend ...' just
seems rather unattached.

        For what it's worth, this is making some *very* cobwebbed
portions of my brain think, "Y'know, this looks like ObjC (circa 1996,
via Webobjects) on drugs."

> > I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
> > qr{} and qw{} constructs
>
> Bingo.

        That part's easy enough. Thanks!

                Elf

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

(There've been a lot of good replies to this, but I'll try to tie it all together a bit.)

I guess I'm just surprised by the implicit reference. In Python
(and Perl, to an even greater if more obscure degree) extensions like
that are quite explicit.

and

For what it's worth, this is making some *very* cobwebbed
portions of my brain think, "Y'know, this looks like ObjC (circa 1996,
via Webobjects) on drugs."

Those two observations are related. Python and Perl both require explicit reference to an object when calling methods, but that makes them quite unusual as object-oriented languages go. Ruby and Objective C are both more in the Smalltalk tradition, where *every* call represents a method on some object or another, and if you don't specify it explicitly, "self" is used. (In that one respect, C++, Java, and C# also are more in the Smalltalk tradition.)

So within a method, "self" is the receiver (the object the method was called upon) and method calls without a specific receiver also go to the same object.

Every class ultimately extends Object, which includes the module Kernel, so the methods defined in Object and Kernel are available everywhere within Ruby. (Unless you take explicit measures to remove them from certain contexts.)

At the top level, the implicit receiver is an otherwise undistinguished instance of Object, which is why methods like "puts" are available outside any other context.

Classes are themselves objects -- instances of Class (which itself extends Module). Within a class definition, but outside a method definition, "self" is bound to the class being defined. That's why "def self.append_features" defines a class method rather than an instance method. You'll see attributes defined with constructs like attr, attr_reader, attr_writer, and attr_accessor: those are private methods defined in Module, and since the class is an instance of Module, you can call those methods on the class. You'll also occasionally see something like this:

     class Something
         class <<self # what's this?
             def meth1
                 # ...
             end
             def meth2
                 # ...
             end
         end
     end

"class <<self" opens a context in which method definitions define class methods. So the above is basically the same as this:

     class Something
         def self.meth1
             # ...
         end
         def self.meth2
             # ...
         end
     end

The second version is, to my mind, much clearer to the beginner.

(Oh, and one more thing: I suspect even _why would admit that the code he highlights on RedHanded is rarely ideal for newcomers to Ruby. :slight_smile:

---Glenn

···

On Sep 28, 2005, at 3:11 PM, Elf M. Sternberg wrote:

oops, that should have been

attr_accessor :a

( which is again a method call against self which because it's inside
of a class definition *IS* the class object that's being
built/modified )

j.

···

On 9/28/05, Jeff Wood <jeff.darklight@gmail.com> wrote:

Actually everything you do in ruby has a receiving object reference
under the covers...

if you do obj.method you are explicitly setting the receiving object
... Other wise, it's always implicitly SELF

And to mess with your brain a bit more, you can do an instance_eval
where you set self to some other object ...

class Blah
    attr_accessor: a
end

obj1 = Blah.new
obj2 = Blah.new

obj1.instance_eval do
  @a = 1
end

obj2.instance_eval do
  @a = 2
end

... remember that there are actually VERY few keywords in Ruby....
everything else is a method on some object in the system ...

when you define functions in a script outside of a class definition,
self is still there for a silent single instance of Object that wraps
everything in your script.

... once you get used to that, it's pretty happy sailing.

Welcome to Ruby ... we hope you enjoy the ride.

j.

On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote:
> James Edward Gray II <james@grayproductions.net> writes:
>
> > On Sep 28, 2005, at 1:46 PM, Elf M. Sternberg wrote:
>
> > Welcome to Ruby. Hopefully it will stop baffling you very soon now. :wink:
>
> Thank you. One can only hope.
>
> > > The first is from
> > > http://redhanded.hobix.com/bits/hyperextended.html, and my question is
> > > about the 'extend' keyword there. Where does that came from? In what
> > > object is it defined?
>
> > It is defined in Object.
>
> I guess I'm just surprised by the implicit reference. In Python
> (and Perl, to an even greater if more obscure degree) extensions like
> that are quite explicit. It is not immediately obvious to me that
> 'extend' is a part of Object.
>
> It's all a matter of familiarity. I wouldn't be surprised to
> see something more like self.extend(...), but the 'extend ...' just
> seems rather unattached.
>
> For what it's worth, this is making some *very* cobwebbed
> portions of my brain think, "Y'know, this looks like ObjC (circa 1996,
> via Webobjects) on drugs."
>
> > > I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's
> > > qr{} and qw{} constructs
> >
> > Bingo.
>
> That part's easy enough. Thanks!
>
> Elf
>
>

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

--
"http://ruby-lang.org -- do you ruby?"

Jeff Wood

I'm not sure what you are trying to show here. You build accessor methods but you never call them, as you just set the instance variable directly.

James Edward Gray II

···

On Sep 28, 2005, at 7:15 PM, Jeff Wood wrote:

oops, that should have been

attr_accessor :a

( which is again a method call against self which because it's inside
of a class definition *IS* the class object that's being
built/modified )