I’m learning Ruby and I’d like some criticism on a program that I wrote.
It interfaces with iTunes and runs through all the songs, (reasonably)
ensuring proper title capitalization. It’s a small program and I would
have
simply posted except that, for some unknown reason, MS Outlook Express
keeps
converting the tabs into single spaces.
I’m open to comments on style versus what is standard protocol for
the
Ruby community, as well.
I hope the program may be as useful to any of you as it is for me…
Is there a better way to do this? Perhaps some way to simply iterate
over every element other than the first one? Something that avoid a check
every iteration?
If you don’t mind clobbering ‘list’:
do_something_for_first(list.shift)
list.each do |item|
do_something_else(item)
end
or if you can’t alter list, how about:
do_something_for_first(list[0])
list[1…-1].each do |item| …
When faced with problems like that I find it handy to fire up irb and
just try different things until the solution emerges. It also helps to
have the pages for ‘Enumerable’ and ‘Array’ bookmarked in Programming
Ruby.
The error is:
C:\tools\scripts\test>ruby itunes.rb
itunes.rb:4:in `ole_methods’: Failed to GetTypeInfo (RuntimeError)
HRESULT error code:0x8002801d
Library not registered. from itunes.rb:4
While ole works fine, because I can run:
require ‘win32ole’
Works for me. Not too helpful for your particular problem, but it does
narrow it down to your machine
What version of ruby are you running? Have you tried using the
Windows OLE browser to find the iTunes OLE methods? The error looks
like something is wrong with the iTunes OLE bindings on your machine
and not the ruby win32 hooks.
I hate to even type this, but you might try reinstalling iTunes and
see if the problem goes away.
On Jul 6, 2006, at 7:53 AM, Just Another Victim of the Ambient
Morality wrote:
first = false
else
# do something else for every other item
end
end
Is there a better way to do this?
i’m not happy with the suggested solutions. i think the inject
solution is OK when it works, and next best is each_with_index. but i
think worrying about indexes is too low level when we don’t actually
want to deal with numbers. it’s worse when you care about the last
iteration and have to worry about off-by-one errors (you need to do
something special on list.length-1) what might be nicer is either
variable capture in loops (i guess that is rejected because it’s too
confusing?) or each_with_first_last (with a shorter name).
it’d work like:
list.each_with_first_last do |item, state|
if state.first?
#…
elsif state.last?
#…
else
#…
end
end
does anyone have a good idea for what to name this?
also what order should the arguments be in? inject is memo,item and
each_with_index is item,index…
i’m not happy with the suggested solutions. i think the inject
solution is OK when it works, and next best is each_with_index. but i
think worrying about indexes is too low level when we don’t actually
want to deal with numbers. it’s worse when you care about the last
iteration and have to worry about off-by-one errors (you need to do
something special on list.length-1) what might be nicer is either
variable capture in loops (i guess that is rejected because it’s too
confusing?) or each_with_first_last (with a shorter name).
You might want to search the archives of ruby-talk - IIRC we had
several lenghty discussions about these kind of problems. I
personally didn’t yet need these. And if, the boolean toggle is ok for
me.
Everybody else seems to be focusing on your “first, rest” question. You
also asked about general coding style and correctness…
I’m a newbie too, so take this with a grain of salt unless one of the
senior members agrees with me. The thing I found most notable about
your code overall was the use of { } for multi-line blocks. This is
certainly legal, but I think it is considered poor form, as I don’t ever
see it in ruby code listed here or in books. As I understand it, the
preferred way is to use {} for blocks that are all on one line, and do -
end pair for multi-line blocks.
best,
jp
Just Another Victim of the Ambient M. wrote:
I’m learning Ruby and I’d like some criticism on a program that I wrote.
It interfaces with iTunes and runs through all the songs, (reasonably)
ensuring proper title capitalization. It’s a small program and I would
have
simply posted except that, for some unknown reason, MS Outlook Express
keeps
converting the tabs into single spaces.
I’m open to comments on style versus what is standard protocol for
the
Ruby community, as well.
I hope the program may be as useful to any of you as it is for me…
i think worrying about indexes is too low level when we don’t actually want to deal with
numbers.
I agree.
It’s an Interesting problem. I came up with the following way, but
it’s sort of ugly. Too bad there isn’t a syntax for calling methods
w/ multiple blocks.
class Array
def borders(head = nil, tail = nil, &block)
a = self.dup
if head
head[a.shift]
end
if tail
t = a.pop
end
a.each &block
if tail
tail[t]
end
end
end
You just give optional blocks for what to do on the first and last
iterations. Actually it would probably be better if you specified
them by keyword, but it’s already ugly enough as is =)
x = [1,2,3,4,5,6,7]
x.borders(
lambda do |h|
puts h * 10
end,
lambda do |t|
puts t + 3
end) do |i|
puts i
end
The error is:
C:\tools\scripts\test>ruby itunes.rb
itunes.rb:4:in `ole_methods’: Failed to GetTypeInfo (RuntimeError)
HRESULT error code:0x8002801d
Library not registered. from itunes.rb:4
To chime in with the other responses, it sounds like the iTunes.exe, or
whatever it’s called, is not registered as automation server on your
machine. You might try logging into the directory where the executable
is installed, and running the following command line:
end pair for multi-line blocks.
Honestly I do not think so, personally I prefer do…end to {…} unless
{…}
looks prettier.
I too see a tendency to use {} on short blocks but would not go so far
to
say that e.g.
File.open(FILE)’ {
|f|
f.each {
…
}
}
is bad or even uncommon practice.
The liberty to use do…end or {} is given on purpose.