Prev: unsubscribe
Next: Compare two objects
From: Robert Dober on 16 Jun 2010 13:26 On Wed, Jun 16, 2010 at 11:31 AM, Ralph Shnelvar <ralphs(a)dos32.com> wrote: > > Is there some way to set the, uh, environment so that "self" need not be > repeated? Only by changing your paradigm and by defining setters like these %w{ step taxes what }.each do | att_name | define_method att_name do | *args | return instance_variable_get( "@#{att_name}") if args.empty? instance_variable_set( "@#{att_name}", args.first) end end def tax *values return @tax if values.empty? @tax = valeus.first end .... HTH R > > (Joke: Hmm, if you get rid of your self, do you commit suicide?) Depends on how many selves you got (cats have 7 IIRC). > > > -- The best way to predict the future is to invent it. -- Alan Kay
From: Josh Cheek on 16 Jun 2010 14:01 [Note: parts of this message were removed to make it a legal post.] On Wed, Jun 16, 2010 at 4:31 AM, Ralph Shnelvar <ralphs(a)dos32.com> wrote: > Consider > > > --- > > def initialize(attributes = nil) > > super attributes > > self.step = 0 > > self.national_debt = 0 > > self.sum_of_income = 0 > > self.sum_of_taxes = 0 > > self.sum_of_happiness = 0 > > self.sum_of_investments = 0 > > self > > end > > --- > > Please focus on the repeated use of self. > > Is there some way to set the, uh, environment so that "self" need not be > repeated? > I don't think so, but if you wanted to dry it up a bit, you could potentially do something like this. class Example METHODS = [ :step, :national_debt, :sum_of_income, :sum_of_taxes, :sum_of_happiness, :sum_of_investments ] DEFAULTS = [ 1 , 2 , [1,2,3,4,5] , 4 , 5 , 6 ] attr_accessor( * METHODS - [:sum_of_income] ) # just to whow that these need not be so simple as the 1:1 method assignment to ivar that attr_accessor gives def sum_of_income=(incomes) summed = incomes.inject { |sum,income| sum + income } @calculated_sum_of_income = summed end def initialize METHODS.zip(DEFAULTS).each { |method,default| send "#{method}=" , default } end end Example.new # => #<Example:0x10019a770 @sum_of_taxes=4, @national_debt=2, @sum_of_investments=6, @step=1, @calculated_sum_of_income=15, @sum_of_happiness=5> (note that I wouldn't mind better method param support built into core Ruby, but doesn't quite apply to this, where it is legitimate to ask how you would differentiate between setters local vars) (Joke: Hmm, if you get rid of your self, do you commit suicide?) > Being a determinist, "I" have often argued that there is no self and there never was. Of course, "I" don't let that stop "me" from being who "I" choose to be. (English is cruel to existential commentary) On Wed, Jun 16, 2010 at 12:26 PM, Robert Dober <robert.dober(a)gmail.com>wrote: > Only by changing your paradigm and by defining setters like these > > %w{ step taxes what }.each do | att_name | > define_method att_name do | *args | > return instance_variable_get( "@#{att_name}") if args.empty? > instance_variable_set( "@#{att_name}", args.first) > end > end > > def tax *values > return @tax if values.empty? > @tax = valeus.first > end > .... > > This is the approach _why took in Dwemthy's Array. http://mislav.uniqpath.com/poignant-guide/book/chapter-6.html#section3 (best read with the soundtrack http://s3.amazonaws.com/mislav.baconfile.com/poignant-guide%2Fchapter-6-downtown.mp3 )
From: Rick DeNatale on 16 Jun 2010 15:18 On Wed, Jun 16, 2010 at 1:26 PM, Robert Dober <robert.dober(a)gmail.com> wrote: >> >> (Joke: Hmm, if you get rid of your self, do you commit suicide?) > Depends on how many selves you got (cats have 7 IIRC). No a cat has 9 lives, not 9 selves. Perhaps you were thinking of the Dr. Who has had more selves that a cat has lives! I'll leave it to the reader to decide if that was two sentences, or one with a missing comma and pronoun. <G> -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Github: http://github.com/rubyredrick Twitter: @RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale
From: Josh Cheek on 16 Jun 2010 15:23 [Note: parts of this message were removed to make it a legal post.] On Wed, Jun 16, 2010 at 1:45 PM, Rein Henrichs <reinh(a)reinh.com> wrote: > Just set the instance variables yourself. Stop replacing clear, explicit > code with metaprogramming magic that you can't understand the day after you > write it. > The original post did not use instance variables, so there is no way to know that the "self.step = 0" is the same as "@step = 0". Hence my explicit decision to make sum_of_income a method which must perform calculations, and accesses an ivar that is not named after the method. Besides I think that is not something you should do, because it means you are accessing ivars all over the place, which couples implementation. If you always use the setter, then you have a gate keeper to that var, and can easily change implementation later, without having to go hunt down all the places you used the ivars.
From: Rick DeNatale on 16 Jun 2010 15:56
On Wed, Jun 16, 2010 at 3:23 PM, Josh Cheek <josh.cheek(a)gmail.com> wrote: > Besides I think that is not something you should do, because it means you > are accessing ivars all over the place, which couples implementation. If you > always use the setter, then you have a gate keeper to that var, and can > easily change implementation later, without having to go hunt down all the > places you used the ivars. This is a teapot which holds a tempest which has been brewing for 30 years or more among users of languages like Ruby. Kent Beck covers this pretty well in his book Smalltalk Best Practice Patterns, the two patterns "direct variable access" and "indirect variable access" are two of the patterns in the book which are most applicable to Ruby. direct variable access as the name implies is accessing an instance variable directly by name indirect variable access is ALWAYS using getter and setter methods to access a variable. Kent describes the two as a tradeoff between simplicity and readability (direct) vs. flexibility. Kent describes an experiment where he compared some Smalltalk code he had written for a client who insisted on indirect variable access with code he wrote for himself using direct variable access. He found that he could read the dva code much more fluently, because he found that everytime he ran across code like a = self x He paused just a bit to recognize that x was "just a getter" and not some other kind of method. In Smalltalk methods always need an explicit receiver so that you need to use "self x" instead of just x. Ruby's support for implicit receivers in this case allows for 'bare' getter invocations, which actually exacerbates this because now a = x Might be a method call, but x might just be a local variable. You need to widen the context when reading such code to determine which case it is. And the reason that in Ruby you can't call a setter with just x = 1 is because even the Ruby parser can't tell that x is a method, so if it hasn't seen it before in the local context as a method call it assumes it's a local and defines it so if needed. On the other hand Ruby's use of the @ sigil to mark instance variable names makes it completely clear that you are accessing an instance variable if you use direct access. The main argument for indirect variable access is that it makes it easier on subclasses because they can change how the 'attribute' is implemented and inherited methods will use the overrided implementation. This is true, and when you are building subclasses, it can be useful, HOWEVER, in the course of programming in dynamically typed languages over nearly 30 years in my case, I've matured to the point where I realize that subclassing is a powerful tool, which, like many powerful tools can be dangerous if not wielded with care. In fact that's one of the main reasons I dislike statically typed "OO" languages, because they force you to use inheritance to describe a type hierarchy, rather than applying it with care when it makes sense for implementaion. Kent basically advises using direct variable access UNLESS indirect variable access is more appropriate, and in either case to use one or the other consistently for a given class and its subclasses. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Github: http://github.com/rubyredrick Twitter: @RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale |