Exceptional Rails Developer

On 2 Oct 2009, at 13:15, Aldric G. wrote:

do this". The difference in mindset is astounding :slight_smile:
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.

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?

Cheers,
James

On Oct 2, 9:54 am, James F. [email protected]
wrote:

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?

Take a look at method_missing.

http://ruby-doc.org/core/classes/Kernel.html#M005925

Yes, that’s working very nicely. Cheers! I wouldn’t have found that on
my own.

James

On Fri, Oct 2, 2009 at 4:54 PM, James F.
[email protected] wrote:

def initialize(*configs)
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?

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

irb(main):015:0> c = Config.new
=> #Config:0xb7db3f78
irb(main):016:0> c.name=“test”
=> “test”
irb(main):017:0> c2 = Config.new
=> #Config:0xb7dad038
irb(main):018:0> c2.name = “test2”
=> “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
=> nil
irb(main):050:0> csel = ConfigSelection.new c,c2
=> #<ConfigSelection:0xb7d9c198 @configs=[#<Config:0xb7db3f78
@name=“test”>, #<Config:0xb7dad038 @name=“test2”>]>
irb(main):051:0> csel.name=“changed”
=> “changed”
irb(main):052:0> csel
=> #<ConfigSelection:0xb7d9c198 @configs=[#<Config:0xb7db3f78
@name=“changed”>, #<Config:0xb7dad038 @name=“changed”>]>

Hope this gives you some ideas,

Jesus.

Hi –

On Sat, 3 Oct 2009, Jesús Gabriel y Galán wrote:

class ConfigSelection

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?
irb(main):018:0> c2.name = “test2”
irb(main):049:1> end
=> nil
irb(main):050:0> csel = ConfigSelection.new c,c2
=> #<ConfigSelection:0xb7d9c198 @configs=[#<Config:0xb7db3f78
@name=“test”>, #<Config:0xb7dad038 @name=“test2”>]>
irb(main):051:0> csel.name=“changed”
=> “changed”
irb(main):052:0> csel
=> #<ConfigSelection:0xb7d9c198 @configs=[#<Config:0xb7db3f78
@name=“changed”>, #<Config:0xb7dad038 @name=“changed”>]>

While it’s probably not likely, it is possible that you’ll get some
false positives there. For example, if Config includes a module with a
method that ConfigSelection doesn’t have, and then you call that
method on a ConfigSelection instance… Like I said, not likely :slight_smile:
But it could happen. It’s probably best at least to toss in a ‘false’:

if Config.instance_methods(false)…

(but also beware that in 1.9, the *methods methods return arrays of
symbols).

David

Brilliant. Thanks!

Hi –

On Fri, 2 Oct 2009, James F. wrote:

def initialize(*configs)
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

On Oct 2, 10:54 am, James F. [email protected]
wrote:

def initialize(*configs)
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?

require ‘facets/enumerable/every’
s = [a,b]
s.every.name = “s”

On Friday 02 October 2009 07:15:36 am Aldric G. wrote:

As an obsessive problem solver myself this baffles me, but it seems to
be the normal human condition. The moral of the story being, there’s
no place for normal human beings in software development :wink:

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 :slight_smile:

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.

On Friday 02 October 2009 05:10:06 am Eleanor McHugh wrote:

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

Some of these people are the people who will grow up to use Visual
Basic, and
enable “on error resume next”.

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.

On Fri, Oct 2, 2009 at 8:18 PM, David M. [email protected]
wrote:

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!”


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