Exceptional Rails Developer

E

Eleanor McHugh

I've come to accept that "How does this work?" is not the first
question
that most people ask. Usually, the first thing people say is "I want
to
do this". The difference in mindset is astounding :)

Even when I was little I was painfully aware of the difference. When I
used to ask "why?" what I always really meant was: explain to me
everything you know about this so I'm not completely clueless when I
disassemble it (and I pretty much disassembled everything in the
house). When my friends asked "why?" they always seemed to mean
"what's in it for me". Funnily enough none of them have childhood
scars from screwdrivers and soldering irons either lol


Ellie

Being and Doing are merely useful abstractions for the time-dependent
asymmetry of phase space.
 
J

James French

Hi,

I want to be able to do operations to a selection of objects, something lik=
e this:

class Config
attr_accessor :name
end

class ConfigSelection

def initialize(*configs)
@configs =3D configs
end

def name=3D(n)
@configs.each{|c| c.name =3D n}
end
=20
end

a =3D Config.new
a.name =3D "a"

b =3D Config.new
b.name =3D "b"

s =3D ConfigSelection.new(a, b)
s.name =3D "s"


I was wondering if there might be a more elegant way of doing this, without=
having to explicitly duplicate all of Config's attributes in ConfigSelecti=
on?

Cheers,
James
 
J

James French

Yes, that's working very nicely. Cheers! I wouldn't have found that on my o=
wn.

James
-----Original Message-----
From: Yossef Mendelssohn [mailto:[email protected]]
Sent: 02 October 2009 16:11
To: ruby-talk ML
Subject: Re: operating on a selection of objects
=20
I was wondering if there might be a more elegant way of doing this,
without having to explicitly duplicate all of Config's attributes in
ConfigSelection?
=20
Take a look at method_missing.
=20
http://ruby-doc.org/core/classes/Kernel.html#M005925
=20
 
J

Jesús Gabriel y Galán

Hi,

I want to be able to do operations to a selection of objects, something l= ike this:

class Config
=A0attr_accessor :name
end

class ConfigSelection

=A0def initialize(*configs)
=A0 =A0@configs =3D configs
=A0end

=A0def name=3D(n)
=A0 [email protected]{|c| c.name =3D n}
=A0end

end

a =3D Config.new
a.name =3D "a"

b =3D Config.new
b.name =3D "b"

s =3D ConfigSelection.new(a, b)
s.name =3D "s"


I was wondering if there might be a more elegant way of doing this, witho=
ut having to explicitly duplicate all of Config's attributes in ConfigSelec=
tion?

This is a way, with the restriction that it only checks instance
methods defined in the class:

irb(main):015:0> c =3D Config.new
=3D> #<Config:0xb7db3f78>
irb(main):016:0> c.name=3D"test"
=3D> "test"
irb(main):017:0> c2 =3D Config.new
=3D> #<Config:0xb7dad038>
irb(main):018:0> c2.name =3D "test2"
=3D> "test2"

irb(main):041:0> class ConfigSelection
irb(main):042:1> def method_missing meth, *args, &blk
irb(main):043:2> if Config.instance_methods.include? meth.to_s
irb(main):044:3> @configs.each {|c| c.send meth, *args, &blk}
irb(main):045:3> else
irb(main):046:3* super
irb(main):047:3> end
irb(main):048:2> end
irb(main):049:1> end
=3D> nil
irb(main):050:0> csel =3D ConfigSelection.new c,c2
=3D> #<ConfigSelection:0xb7d9c198 @configs=3D[#<Config:0xb7db3f78
@name=3D"test">, #<Config:0xb7dad038 @name=3D"test2">]>
irb(main):051:0> csel.name=3D"changed"
=3D> "changed"
irb(main):052:0> csel
=3D> #<ConfigSelection:0xb7d9c198 @configs=3D[#<Config:0xb7db3f78
@name=3D"changed">, #<Config:0xb7dad038 @name=3D"changed">]>

Hope this gives you some ideas,

Jesus.
 
J

James French

Brilliant. Thanks!
-----Original Message-----
From: Jes=FAs Gabriel y Gal=E1n [mailto:[email protected]]
Sent: 02 October 2009 16:28
To: ruby-talk ML
Subject: Re: operating on a selection of objects
=20
Hi,

I want to be able to do operations to a selection of objects, something like this:

class Config
=A0attr_accessor :name
end

class ConfigSelection

=A0def initialize(*configs)
=A0 =A0@configs =3D configs
=A0end

=A0def name=3D(n)
=A0 [email protected]{|c| c.name =3D n}
=A0end

end

a =3D Config.new
a.name =3D "a"

b =3D Config.new
b.name =3D "b"

s =3D ConfigSelection.new(a, b)
s.name =3D "s"


I was wondering if there might be a more elegant way of doing this,
without having to explicitly duplicate all of Config's attributes in
ConfigSelection?
=20
This is a way, with the restriction that it only checks instance
methods defined in the class:
=20
irb(main):015:0> c =3D Config.new
=3D> #<Config:0xb7db3f78>
irb(main):016:0> c.name=3D"test"
=3D> "test"
irb(main):017:0> c2 =3D Config.new
=3D> #<Config:0xb7dad038>
irb(main):018:0> c2.name =3D "test2"
=3D> "test2"
=20
irb(main):041:0> class ConfigSelection
irb(main):042:1> def method_missing meth, *args, &blk
irb(main):043:2> if Config.instance_methods.include? meth.to_s
irb(main):044:3> @configs.each {|c| c.send meth, *args, &blk}
irb(main):045:3> else
irb(main):046:3* super
irb(main):047:3> end
irb(main):048:2> end
irb(main):049:1> end
=3D> nil
irb(main):050:0> csel =3D ConfigSelection.new c,c2
=3D> #<ConfigSelection:0xb7d9c198 @configs=3D[#<Config:0xb7db3f78
@name=3D"test">, #<Config:0xb7dad038 @name=3D"test2">]>
irb(main):051:0> csel.name=3D"changed"
=3D> "changed"
irb(main):052:0> csel
=3D> #<ConfigSelection:0xb7d9c198 @configs=3D[#<Config:0xb7db3f78
@name=3D"changed">, #<Config:0xb7dad038 @name=3D"changed">]>
=20
Hope this gives you some ideas,
=20
Jesus.
 
D

David A. Black

Hi --

Hi,

I want to be able to do operations to a selection of objects, something like this:

class Config
attr_accessor :name
end

class ConfigSelection

def initialize(*configs)
@configs = configs
end

def name=(n)
@configs.each{|c| c.name = n}
end

end

a = Config.new
a.name = "a"

b = Config.new
b.name = "b"

s = ConfigSelection.new(a, b)
s.name = "s"


I was wondering if there might be a more elegant way of doing this, without having to explicitly duplicate all of Config's attributes in ConfigSelection?

Here's a different approach from the method_missing ones, just to give
you some further ideas:

class Config
ATTRIBUTES = [:name, :age, :email]
attr_accessor *ATTRIBUTES
end

class ConfigSelection

def initialize(*configs)
@configs = configs
end

Config::ATTRIBUTES.each do |attr|
define_method("#{attr}=") do |val|
@configs.each {|c| c.send("#{attr}=", val) }
end
end
end


David
 
T

trans

Hi,

I want to be able to do operations to a selection of objects, something l= ike this:

class Config
=A0 attr_accessor :name
end

class ConfigSelection

=A0 def initialize(*configs)
=A0 =A0 @configs =3D configs
=A0 end

=A0 def name=3D(n)
=A0 =A0 @configs.each{|c| c.name =3D n}
=A0 end

end

a =3D Config.new
a.name =3D "a"

b =3D Config.new
b.name =3D "b"
s =3D ConfigSelection.new(a, b)
s.name =3D "s"

I was wondering if there might be a more elegant way of doing this, witho=
ut having to explicitly duplicate all of Config's attributes in ConfigSelec=
tion?

require 'facets/enumerable/every'
s =3D [a,b]
s.every.name =3D "s"
 
D

David Masover

I've come to accept that "How does this work?" is not the first question
that most people ask. Usually, the first thing people say is "I want to
do this". The difference in mindset is astounding :)

I wish I had people like that.

Usually, the "I want to do this" already assumes a particular way that it
should work. No one ever asks "I want to send mail to a list of people on a
regular basis. What's the best way to do that?"

No, they ask "I want to do mail merge using Outlook and Excel. What's the best
way to do that?"

That immediately cuts off what is truly the best way, which starts with,
"Don't use Outlook or Excel."

I'd much rather have people who start at the level of abstraction they
actually need, and let me work out the details. As they say, there's nothing
more dangerous than a little knowledge.
 
D

David Masover

The best teacher of "the right way" is experience, and experience
mostly comes from doing things the wrong way and then having to clear
up the mess at some appreciable cost to yourself.

That is true for the species in general. It is not true for the individual.

For example, we, as a species, have enough experience to know that shooting
yourself in the foot will probably hurt, and may even require that foot to be
amputated. It would be ridiculous to expect every individual to do that.

Having to clear up the mess is helpful, except for the situation where you
don't realize what a mess you're in.
I suspect most of
the problems big companies have (and not just with coders) is that
when a person works on one small problem and then passes their output
along to a coworker in an equally myopic position, the producers of
mess are rarely if ever penalised.

That is a large part of it. And having responsibility for the mess would mean
someone would try that much harder to avoid the mess in the first place.

But the key word there is "avoid".
I guess you probably don't approve of rescue nil in ruby either lol

In production? Nope.

In development? Be careful, because it might survive till production. I'd much
rather replace the troublesome code with an explicit stub than have something
that half-works, maybe, this time.

It's actually something I'm starting to dislike about shell scripting:

#!/bin/sh
source config/variables.
rm -rf ./$BACKUP_DIR
cp -a $FILES ./$BACKUP_DIR
...

Obivously, BACKUP_DIR is assumed to be defined in config/variables. But if that
file doesn't exist, "source" will raise an error -- but the next line will
proceed. If the file does exist, but doesn't define BACKUP_DIR, the result is
the same -- in either case, BACKUP_DIR will be expanded to an empty string,
resulting in:

rm -rf ./

It's a contrived example, but not too far off from reality. And I don't think
anyone should have to see their files go away to learn to do proper error
checking in their shell scripts. It can be as easy as adding a && to the end
of each line except the last -- and there's probably some even easier flag to
set...

Same with Perl and "use strict; use warnings;" -- I had to learn that those
exist first before I could use them properly. If I was only to learn from
experience, I'd probably have written years worth of programs in which
misspelling a variable didn't raise an error, but instead gave me a null
value.
 
R

Rick DeNatale

I wish I had people like that.

Usually, the "I want to do this" already assumes a particular way that it
should work. No one ever asks "I want to send mail to a list of people on a
regular basis. What's the best way to do that?"

No, they ask "I want to do mail merge using Outlook and Excel. What's the best
way to do that?"

That immediately cuts off what is truly the best way, which starts with,
"Don't use Outlook or Excel."

So the answer to the first question is "Mu!"
http://en.wikipedia.org/wiki/Mu_(negative)

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 

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,787
Messages
2,569,627
Members
45,328
Latest member
66Teonna9

Latest Threads

Top