Just curious if there is a more elegant way to set a variable if it happens to not exist yet. I often find I am doing somthing like the following: regex = '''' 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } Is there some prettier way to within the second line create the variable if it does not exist yet? The above just looks ugly. I know I could use a class variable but that also does not seem right as I do not need it to be a class variable: 10.times { @regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Friday, April 22, 2011 10:32:35 AM UTC-6, DK wrote:> > Just curious if there is a more elegant way to set a variable if it happens > to not exist yet. I often find I am doing somthing like the following: > > regex = '''' > 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } > > Is there some prettier way to within the second line create the variable if > it does not exist yet? The above just looks ugly. I know I could use a class > variable but that also does not seem right as I do not need it to be a class > variable: > > 10.times { @regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } > >Having no idea what the context is I''ll try to answer: Since the code where you''re modifying your variable is w/in a block, any variables referenced therein that don''t already exist (outside the block) won''t exist outside the block once after it has run:> $ cat test.rb > 1.times { hi = "hello" } > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" > puts hi > $ ruby test.rb > NOT DEFINEDThus, for your block to have any effect on local variables that exist in the enclosing scope these variables must already "exist" before the block. This means the parser must see the local variable (in some context where it is clear it is a local variable and not a method call, such as in an assignment statement) before the block definition in the enclosing scope. So, assuming I understand your intent, the answer is no. The local must already be defined (whether initialized with an actual value is another matter (*see example below)) or you should use an instance, class, or global. * (> $ cat test.rb > hi = nil if false # defines hi even though assignment never executed > 1.times { hi = "hello" } > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" > puts hi > $ ruby test.rb > hello byeI don''t know if this helps any or not... -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Fri, Apr 22, 2011 at 1:15 PM, Kendall Gifford <zettabyte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> On Friday, April 22, 2011 10:32:35 AM UTC-6, DK wrote: >> >> Just curious if there is a more elegant way to set a variable if it >> happens to not exist yet. I often find I am doing somthing like the >> following: >> >> regex = '''' >> 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >> >> Is there some prettier way to within the second line create the variable >> if it does not exist yet? The above just looks ugly. I know I could use a >> class variable but that also does not seem right as I do not need it to be a >> class variable: >> >> 10.times { @regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >> >> > Having no idea what the context is I''ll try to answer: > > Since the code where you''re modifying your variable is w/in a block, any > variables referenced therein that don''t already exist (outside the block) > won''t exist outside the block once after it has run: > > > $ cat test.rb > > 1.times { hi = "hello" } > > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" > > puts hi > > $ ruby test.rb > > NOT DEFINED > > Thus, for your block to have any effect on local variables that exist in > the enclosing scope these variables must already "exist" before the block. > This means the parser must see the local variable (in some context where it > is clear it is a local variable and not a method call, such as in an > assignment statement) before the block definition in the enclosing scope. > > So, assuming I understand your intent, the answer is no. The local must > already be defined (whether initialized with an actual value is another > matter (*see example below)) or you should use an instance, class, or > global. > > * ( > > $ cat test.rb > > hi = nil if false # defines hi even though assignment never executed > > 1.times { hi = "hello" } > > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" > > puts hi > > $ ruby test.rb > > hello bye > > I don''t know if this helps any or not... >Thanks Kendall... actually I think I confused things by putting the block but I think the answer is still pretty much the same for a case such as the following, that if I did not want to first create the variable by assignment, that I should use an instance, class or global as you say. regex = '''' regex += ''something'' ... regex += ''something else'' ... regex += ''and another something''> -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
I guess you could do something like this: x = defined?(x) ? x+="string" : "" You can assign a value to a variable if it doesn''t exist like this: s ||= "" but in your case you want to use the operand + so the string needs to exist. Also an alternative for the loop example regex = '''' 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } could be changed to regex = ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' *10 hope it helps On Fri, Apr 22, 2011 at 1:19 PM, David Kahn <dk-rfEMNHKVqOwNic7Bib+Ti1W1rNmOCjRP@public.gmane.org>wrote:> > > On Fri, Apr 22, 2011 at 1:15 PM, Kendall Gifford <zettabyte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote: > >> On Friday, April 22, 2011 10:32:35 AM UTC-6, DK wrote: >>> >>> Just curious if there is a more elegant way to set a variable if it >>> happens to not exist yet. I often find I am doing somthing like the >>> following: >>> >>> regex = '''' >>> 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >>> >>> Is there some prettier way to within the second line create the variable >>> if it does not exist yet? The above just looks ugly. I know I could use a >>> class variable but that also does not seem right as I do not need it to be a >>> class variable: >>> >>> 10.times { @regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >>> >>> >> Having no idea what the context is I''ll try to answer: >> >> Since the code where you''re modifying your variable is w/in a block, any >> variables referenced therein that don''t already exist (outside the block) >> won''t exist outside the block once after it has run: >> >> > $ cat test.rb >> > 1.times { hi = "hello" } >> > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" >> > puts hi >> > $ ruby test.rb >> > NOT DEFINED >> >> Thus, for your block to have any effect on local variables that exist in >> the enclosing scope these variables must already "exist" before the block. >> This means the parser must see the local variable (in some context where it >> is clear it is a local variable and not a method call, such as in an >> assignment statement) before the block definition in the enclosing scope. >> >> So, assuming I understand your intent, the answer is no. The local must >> already be defined (whether initialized with an actual value is another >> matter (*see example below)) or you should use an instance, class, or >> global. >> >> * ( >> > $ cat test.rb >> > hi = nil if false # defines hi even though assignment never executed >> > 1.times { hi = "hello" } >> > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" >> > puts hi >> > $ ruby test.rb >> > hello bye >> >> I don''t know if this helps any or not... >> > > Thanks Kendall... actually I think I confused things by putting the block > but I think the answer is still pretty much the same for a case such as the > following, that if I did not want to first create the variable by > assignment, that I should use an instance, class or global as you say. > > regex = '''' > regex += ''something'' > ... > regex += ''something else'' > ... > regex += ''and another something'' > > >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Talk" group. >> To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >> To unsubscribe from this group, send email to >> rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >> For more options, visit this group at >> http://groups.google.com/group/rubyonrails-talk?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. >-- Jazmin -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Fri, Apr 22, 2011 at 1:42 PM, Jazmin <jazminschroeder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I guess you could do something like this: > x = defined?(x) ? x+="string" : ""Thanks Jazmin, this is the kind of thing I was looking for although I guess in the end it is probably less readable than just assigning the variable at the top, hmmm.. and am seeing also why it wouldnt make sense to override a base class like object or something with the above to handle undefined cases as it would not know the type of variable to create.> > You can assign a value to a variable if it doesn''t exist like this: > s ||= "" > but in your case you want to use the operand + so the string needs to > exist. > > Also an alternative for the loop example > regex = '''' > 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } > > could be changed to > regex = ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' *10 > > hope it helps > > On Fri, Apr 22, 2011 at 1:19 PM, David Kahn <dk-rfEMNHKVqOwNic7Bib+Ti1W1rNmOCjRP@public.gmane.org>wrote: > >> >> >> On Fri, Apr 22, 2011 at 1:15 PM, Kendall Gifford <zettabyte-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote: >> >>> On Friday, April 22, 2011 10:32:35 AM UTC-6, DK wrote: >>>> >>>> Just curious if there is a more elegant way to set a variable if it >>>> happens to not exist yet. I often find I am doing somthing like the >>>> following: >>>> >>>> regex = '''' >>>> 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >>>> >>>> Is there some prettier way to within the second line create the variable >>>> if it does not exist yet? The above just looks ugly. I know I could use a >>>> class variable but that also does not seem right as I do not need it to be a >>>> class variable: >>>> >>>> 10.times { @regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >>>> >>>> >>>> >>> Having no idea what the context is I''ll try to answer: >>> >>> Since the code where you''re modifying your variable is w/in a block, any >>> variables referenced therein that don''t already exist (outside the block) >>> won''t exist outside the block once after it has run: >>> >>> > $ cat test.rb >>> > 1.times { hi = "hello" } >>> > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" >>> > puts hi >>> > $ ruby test.rb >>> > NOT DEFINED >>> >>> Thus, for your block to have any effect on local variables that exist in >>> the enclosing scope these variables must already "exist" before the block. >>> This means the parser must see the local variable (in some context where it >>> is clear it is a local variable and not a method call, such as in an >>> assignment statement) before the block definition in the enclosing scope. >>> >>> So, assuming I understand your intent, the answer is no. The local must >>> already be defined (whether initialized with an actual value is another >>> matter (*see example below)) or you should use an instance, class, or >>> global. >>> >>> * ( >>> > $ cat test.rb >>> > hi = nil if false # defines hi even though assignment never executed >>> > 1.times { hi = "hello" } >>> > defined?(hi) ? hi += " bye" : hi = "NOT DEFINED" >>> > puts hi >>> > $ ruby test.rb >>> > hello bye >>> >>> I don''t know if this helps any or not... >>> >> >> Thanks Kendall... actually I think I confused things by putting the block >> but I think the answer is still pretty much the same for a case such as the >> following, that if I did not want to first create the variable by >> assignment, that I should use an instance, class or global as you say. >> >> regex = '''' >> regex += ''something'' >> ... >> regex += ''something else'' >> ... >> regex += ''and another something'' >> >> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Ruby on Rails: Talk" group. >>> To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >>> To unsubscribe from this group, send email to >>> rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >>> For more options, visit this group at >>> http://groups.google.com/group/rubyonrails-talk?hl=en. >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Talk" group. >> To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >> To unsubscribe from this group, send email to >> rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org >> For more options, visit this group at >> http://groups.google.com/group/rubyonrails-talk?hl=en. >> > > > > -- > Jazmin > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Apr 22, 12:32 pm, David Kahn <d...-rfEMNHKVqOwNic7Bib+Ti1W1rNmOCjRP@public.gmane.org> wrote:> Just curious if there is a more elegant way to set a variable if it happens > to not exist yet. I often find I am doing somthing like the following: > > regex = '''' > 10.times { regex += ''.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*,.*\n'' } >A mostly unrelated note - if you''re really matching against a pattern like this, you may want to consider changing the .* bits to [^,]* to keep the backtracking under control. I put together a short set of benchmarks: https://gist.github.com/938732 Here''s the results on my system (2010 13" MBP) (1000 iterations, except regex3): user system total real regex1: 2.490000 0.000000 2.490000 ( 2.590084) regex2: 0.050000 0.000000 0.050000 ( 0.048411) regex3 (/100): 25.600000 0.060000 25.660000 ( 26.839205) regex4: 0.080000 0.000000 0.080000 ( 0.090349) regex3 is the same .* pattern as regex1 but with 20 fields instead of 10 - note that in order to benchmark it in a reasonable time I cut the number of iterations from 1000 to 10 - in other words, regex3 would have taken 2560 seconds to complete the whole benchmark. One additional note - make sure you''re not using *any* of these patterns with the Regexp::MULTILINE modifier, which makes ''.'' match newlines as well. I let a single instance matching regex1 run for about 10 minutes before giving up. Here''s an article on this phenomenon (''catastrophic backtracking'') with more detail: http://www.regular-expressions.info/catastrophic.html Hope this helps! --Matt Jones -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.