Ex-Perl coders: Howz it feel to convert to Ruby?

J

Joel VanderWerf

Mauricio said:
And you can be "disciplined" by Chris' criteria while using yield:

def foo(arg, &block)
yield
end

...although this does have a small speed penalty as a Proc object gets
created by the &block construct, IIRC.

Why not just use the rdoc markup as a convention, if you want to be
explicit?

def foo(arg) # :yields: some_useful_object
yield foo(arg)
end
 
M

Markus

It might be interesting to define something like Common Lisp's 'setf'
function, which is a sort of generic setter. So, mutable objects like
strings, arrays, hashes, etc., could all support a 'value=' or
'replace' method which would make them destructively update their
value.

I played around with adding a method Module#become(other) (IIRC)
that would cause an object to replace itself with another; the intended
use was a distribution/persistence layer that could invisibly swap
objects out and replace them with stubs that would then bring back the
original object on access.

Again, if I recall correctly, I got it to the sort-of-working
stage, but bogged down in dealing with the details of some of the
built-in classes, singletons, etc.

-- MarkusQ
 
L

Lennon Day-Reynolds

Actually, I think I just described the 'replace' method, which String,
Array, and Hash all implement...I really should just assume that the
standard library already does anything clever I can think of.
 
B

Brian Wisti

--- Nate Smith said:
Try

print "a" + 1

Won't work -- you have to do

print "a" + 1.to_s


Nate

That "+" means you're building a new string from two Strings. Since the
second operand is not a String, the conversion has to be explicit.

Now, for simple printing, it just occurred to me to test what happens
when you hand a printf-style expression to print, as I might do in the
same situation with Python:

irb > print "a%d" % 1
a1 => nil

So, that's One Way To Do It.

-- Brian Wisti
http://coolnamehere.com/
 
D

David A. Black

Hi --

That "+" means you're building a new string from two Strings. Since the
second operand is not a String, the conversion has to be explicit.

If the second operand responds to to_str, then its response to to_str
will be used in cases where only a string will do:

irb(main):016:0> obj = Object.new
=> #<Object:0x402a6e94>
irb(main):017:0> puts "this is an " + obj
TypeError: cannot convert Object into String
from (irb):17:in `+'
from (irb):17
from :0
irb(main):018:0> def obj.to_str; "implicit string representation!";
end
=> nil
irb(main):019:0> puts "this is an " + obj
this is an implicit string representation!


David
 
B

Brian Wisti

--- "David A. Black said:
Hi --



If the second operand responds to to_str, then its response to to_str
will be used in cases where only a string will do:

irb(main):016:0> obj = Object.new
=> #<Object:0x402a6e94>
irb(main):017:0> puts "this is an " + obj
TypeError: cannot convert Object into String
from (irb):17:in `+'
from (irb):17
from :0
irb(main):018:0> def obj.to_str; "implicit string representation!";
end
=> nil
irb(main):019:0> puts "this is an " + obj
this is an implicit string representation!


David

So we just have Fixnums and similar types not responding to to_s?
Interesting...

-- Brian Wisti
 
D

David A. Black

Hi --

So we just have Fixnums and similar types not responding to to_s?
Interesting...

No, they do respond to to_s, but not to to_str. It's to_str that
provides this kind of masquerading facility.


David
 
R

Robert Klemme

Karl von Laudermann said:
"Robert Klemme" <[email protected]> wrote in message

I can't speak for James, but coming from Java I'm used to using the
concatenation operator, like so:

print "foo" + 1;

This causes an error; you have to call to_s on the number. I find it
unintuitive that specifying multible arguments to the print method is
a way of concatenating them, so I rarely think to use it.

Others might think different about this - I do for example. :) You
simply enumarate things to get printed. Also, it's more efficient to
individually print items than to first concatenate them (creates new temp
instances) and then print that temp String instance. If I have more
complex printouts I use String interpolation with "#{}" or printf anyway.
I also find
it unintuitive that you don't have to call to_s when passing a
non-string argument by itself, but you do when concatenating.

It's perfectly logical because these are two completely unlelated things:
String#+ is something different than the behavior of Kernel#print.
Perhaps
String#+ should be modified to call to_s on its arguments?

It is done deliberately the way it is: String#+ is "intelligent" enough to
invoke #to_str on its arguments; but an instance that has no #to_str
cannot be "legally" concatenated with a String.
2xxx
=> nil
BTW, one actual benefit of using concatenation vs. multiple arguments
is that you can use puts instead of print to get a "\n" for free at
the end, but not in between each component of your string.

Well, you can use puts with interpolation or define a println method if
you really care to save the "\n" typing effort:

module Kernel
private
def println(*args) print *args << "\n" end

def smart_println(*args)
args << "\n" unless /\n$/ =~ args[-1].to_s
print *args
end
end

Kind regards

robert
 
N

Nate Smith

Why do you think this is needed (or nice) for writing a collect!
method? Why cant you just write something like:

class My_collection_class
def [](k)
:
end
def []=(k,v)
:
end
def each_key
:
end
def collect!
each_key { |k| self[k] = yield(self[k]) }
end
end

Very true indeed (that works great). I was more thinking about
collecting for the key and the value in one swoop, but that may be more
trouble than it's worth.

Nate
 

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

Forum statistics

Threads
473,744
Messages
2,569,481
Members
44,900
Latest member
Nell636132

Latest Threads

Top