[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

modify instance variable in a method mixed in from external module

hemant

10/19/2006 3:42:00 AM

I have this gem of a parser that does:

def parse_data data
data.chomp!
while data && data.length > 0
data_array = data.split(/\r?\n/,2)
@chunked_data << data_array[0]
data = data_array[1]

if @chunked_data =~ /(\d{3})(.*)<(.*)>##(.*)##/
dispatch_data
@chunked_data = ""
end
end
end


That is used in several classes as instance methods. Now, I want to
include this method in a module to be DRY. And make this method
available to classes that mixin that module.
The only trouble is, it uses a instance_variable.
Of course...i can keep this method as it is. assuming all the consumer
classes will have their this particular instance variable with same
name.

The other approach could be, as suggested by Eric Hodel on IRC, is to
have some kind of include, that hookes correct instance variable to
the module upon inclusion in the class.

And this bit..almost escaped me.

If i use set_instance_variable or something like that, then still i
won't be able to know the name of that particular instance variable
,right?

if i pass the @chunked_data from the any class to the parse_data
method, i would recieve it as a local variable in method and any
changes to the varible will be lost.
Why can't we have something like C++ reference, where if i modify the
variable in mixed in method, i would effectively change the instance
variable?

Not even that, although in Ruby, AFAIK(which is very little, to tell
the truth) values are passed by reference, even if we pass a local
variable to the parse_data
method and do some modification and try to read back the data in
calling method, changes will be lost.


--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.

4 Answers

Rick DeNatale

10/19/2006 2:51:00 PM

0

On 10/18/06, hemant <gethemant@gmail.com> wrote:
> I have this gem of a parser that does:
>
> def parse_data data
> data.chomp!
> while data && data.length > 0
> data_array = data.split(/\r?\n/,2)
> @chunked_data << data_array[0]
> data = data_array[1]
>
> if @chunked_data =~ /(\d{3})(.*)<(.*)>##(.*)##/
> dispatch_data
> @chunked_data = ""
> end
> end
> end
>
>
> That is used in several classes as instance methods. Now, I want to
> include this method in a module to be DRY. And make this method
> available to classes that mixin that module.
> The only trouble is, it uses a instance_variable.
> Of course...i can keep this method as it is. assuming all the consumer
> classes will have their this particular instance variable with same
> name.

Well, if the receiver of parse_data doesn't have the instance
variable, it will after this method is executed.

In Ruby, instance variables aren't declared/defined in classes, they
are dynamically added to instances as needed.

I'm not clear on just why you need @chunked_data to persist across
invocations, but the only issue I see with guaranteeing that an
instance of the class has this iv is that it's not guaranteed to be
initialized, so in the first iteration of your while loop you might be
doing

nil << data_array[0]

which won't work.

This can be fixed by adding:

@chunked_data ||= ""

before the while loop.

Now one danger is that a class might have an iv called @chunked_data
which it's using for something else. This seems unlikely but you never
know.

If you do this you need to document the use of @chunked_data.

There are likely better ways to design this if you step back a bit,
but we don't know enough about the context to help.

> The other approach could be, as suggested by Eric Hodel on IRC, is to
> have some kind of include, that hookes correct instance variable to
> the module upon inclusion in the class.

I'm not sure what this means, so I can't comment.

> And this bit..almost escaped me.
>
> If i use set_instance_variable or something like that, then still i
> won't be able to know the name of that particular instance variable
> ,right?
>
> if i pass the @chunked_data from the any class to the parse_data
> method, i would recieve it as a local variable in method and any
> changes to the varible will be lost.
> Why can't we have something like C++ reference, where if i modify the
> variable in mixed in method, i would effectively change the instance
> variable?

> Not even that, although in Ruby, AFAIK(which is very little, to tell
> the truth) values are passed by reference, even if we pass a local
> variable to the parse_data
> method and do some modification and try to read back the data in
> calling method, changes will be lost.

In Ruby ALL variables are just references, if you mutate the object
referenced by the variable the object will be changed:

irb(main):005:0> def change(arg, value)
irb(main):006:1> arg << value
irb(main):007:1> end
=> nil
irb(main):008:0> a = "hello"
=> "hello"
irb(main):009:0> change(a, " there.")
=> "hello there."
irb(main):010:0> a
=> "hello there."
irb(main):011:0>

Any mutating methods invoked against the parameter will change the
underlying object. So rather than

arg = ""

you could use

arg.replace("")

Note that the value of a method is the value of the last expression
executed in the method. So this method returns the value of

arg << value

So you could have parse return the chunked data and ask clients to
pass it back on subsequent calls.

I'm not saying that this is a good design, but you seem to need some
understanding of how variables and objects relate.

Another note on variables and references which trips up folks
accustomed to C-like variables:

irb(main):011:0> b = a
=> "hello there."
irb(main):012:0> change(a, " Again!")
=> "hello there. Again!"
irb(main):013:0> a
=> "hello there. Again!"
irb(main):014:0> b
=> "hello there. Again!"

Understand that and you should be further along in understanding the
relationship between variables and object in Ruby.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

hemant

10/20/2006 2:05:00 PM

0

On 10/19/06, Rick DeNatale <rick.denatale@gmail.com> wrote:
> irb(main):011:0> b = a
> => "hello there."
> irb(main):012:0> change(a, " Again!")
> => "hello there. Again!"
> irb(main):013:0> a
> => "hello there. Again!"
> irb(main):014:0> b
> => "hello there. Again!"
>
> Understand that and you should be further along in understanding the
> relationship between variables and object in Ruby.

Thanks Rick...

--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.

Gary DeWaay

9/16/2010 8:55:00 PM

0

In article <i8st86h81ajoqtebtil8qoskmea86bg516@4ax.com>,
foxtrot@null.com says...
>
> rfischer@sonic.net (Ray Fischer) wrote:
>
> >Foxtrot <foxtrot@null.com> wrote:
> >>Goodness, Kevvy. You're very defensive of Tuxedo Obama.
> >
> >You're a nasty, evil bigot.
> >
> >>Obama loves to bow down before others.
> >
> >Given your rabid hatred of Obama it's obvious that you're lying
> >again.
>
> Answer the question:
>
> What's stopping the next attention starved redneck from doing the
> same thing Jones did?
>
> Pictures of Caviar Obama bowing in subservience:
>
> Saudi King.
> http://latimesblogs.latimes.com/.a/6a00d8341c630a53ef012875a01896...
>
> Japanese King.
> http://media.sfexaminer.com/images/Obam...
>
> Mayor of Tampa.
> http://www.nydailynews.com/news/politics/2010/02/01/2010-02-01_president_obama_seemingly_bows_to_tampa_mayor_pam_iorio_in_photog...
>


I go away from Usenet for a few months and Fauxy is still whining about
the same moronic garbage like a 13 year old?

Guess it shouldnt surprise me.



--
How's That Oily Drilly Thing Working Out For Ya?*

-Digby

Foxtrot

9/16/2010 9:25:00 PM

0

Gary DeWaay <dewaay2spikeNOT@sio.midco> wrote:

>foxtrot@null.com says...
>> Answer the question:
>>
>> What's stopping the next attention starved redneck from doing the
>> same thing Jones did?

>I go away from Usenet for a few months and Fauxy is still whining about
>the same moronic garbage like a 13 year old?

Non-answer. Try again.

> What's stopping the next attention starved redneck from doing the
> same thing Jones did?

So why would Obama get involved?