Python to Ruby: Two puzzlements...

E

Elf M. Sternberg

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
 
R

Robert Klemme

Elf M. Sternberg said:
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:
=> ["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:=> 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:
Foo: 1
Bar: 2
=> nil
and why does it need a 'self' in front of it?

Inside the class "self" references the class itself:
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.

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?),
=> "Wed Sep 28 20:56:11 2005\n"

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

double quotes=> "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
 
V

Vincent Foley

%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"]
 
F

Florian Groß

Elf said:
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. ;)
 
C

Caleb Tennis

It's defined in Class:
=> ["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
 
C

Caleb Tennis

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

irb> Foo.class_m
in class method
irb> Foo.instance_m
NoMethodError: undefined method `instance_m' for Foo:Class

irb> a = Foo.new
=> #<Foo:0xb7ca10b8>
irb> a.class_m
NoMethodError: undefined method `class_m' for #<Foo:0xb7ca10b8>
irb> a.instance_m
in instance method

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

irb> a.class
=> Foo
irb> Foo.class
=> Class
 
J

James Edward Gray II

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. ;)
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. ;)
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
 
M

Mark Hubbart

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

=3D> ["extend"]

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

The proof is in the #inspect:

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

cheers,
Mark
 
R

Rob Rypka

------=_Part_6507_19643.1127935688456
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

(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.)

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.exte=
nd

There are a couple more examples that might help you get the gist of extend=
 
B

Brian Mitchell

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 =3D A.new
b =3D 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 =3D Class.new
c =3D 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 =3D> %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.
 
B

Brian Mitchell

A fixed error:

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.
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 =3D A.new
b =3D 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 =3D Class.new
c =3D 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 =3D> %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.
 
M

Matthew Desmarais

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



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

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


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



Buy the Pickaxe! Or read the old one online. ;)

Elf,

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

If there's one thing that I might be able to add (unless someone else=20
has pointed it out already), it's that you should have something called=20
irb thrown in with your ruby installation. Between ri and irb you can=20
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=20
interpreter works when invoked alone on the commend line (except that=20
when you ask it to exit, it does, instead of dropping that silly "Use=20
Ctrl-Z plus Return to exit." line on you.). Basically, you can fire off=20
any ruby that you could run in a script, and so you can see firsthand=20
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=20
mailing list over the past week or so: there's been a discussion about=20
whether the RDE tool from sakazuki-san (=20
http://homepage2.nifty.com/sakazuki/rde_e.html ) is more convenient that=20
the code-running capabilites of SciTe (also packaged with the ruby=20
installation, on windows anyway).

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

mattD
 
F

Florian Groß

James said:
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.
 
G

Gene Tani

(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://www.approximity.com/ruby/Comparison_rb_st_m_java.html
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.
 
L

Logan Capaldo

--Apple-Mail-4--681313474
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed


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."


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


--Apple-Mail-4--681313474--
 
J

Jeff Wood

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 =3D Blah.new
obj2 =3D Blah.new

obj1.instance_eval do
@a =3D 1
end

obj2.instance_eval do
@a =3D 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.
 
J

Jeff Wood

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.
 
J

James Edward Gray II

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 )

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
 
J

Jeff Wood

------=_Part_376_5550536.1127970558299
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

yeah ... the point I was trying to make was simply the point about the
implicit reference to self ... any variable you access, any method you call=
,
anything ... that doesn't have an explicit receiver specified, will use the
implicit reference to self...

the point of the accessor was simply to create the variable, and methods in
as terse a chop as I could ... but, yes, I do agree that I didn't actually
use all I created, so there wasn't any specific gain from it.

... uh ... did that make *ANY* sense ? Just trying to help. =3D)

j.

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


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

Jeff Wood

------=_Part_376_5550536.1127970558299--
 
B

Brian Mitchell

yeah ... the point I was trying to make was simply the point about the
implicit reference to self ... any variable you access, any method you ca= ll,
anything ... that doesn't have an explicit receiver specified, will use t= he
implicit reference to self...

the point of the accessor was simply to create the variable, and methods = in
as terse a chop as I could ... but, yes, I do agree that I didn't actuall= y
use all I created, so there wasn't any specific gain from it.

... uh ... did that make *ANY* sense ? Just trying to help. =3D)

j.

It made enough sense. However, I wouldn't call it all about the
receiver. I would call it scope or binding based. Each binding then
has a special meaning for self and thus the implicit receiver. There
are also other special things to each binding like super.

Brian.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top