On Fri, 24 Sep 2010 20:45:11 -0500, Pen Ttt <myocean135 / yahoo.cn>
wrote in <ad426292d72fc07a0b7b2c11b3f2e764 / ruby-forum.com>:

[snip]

Here goes:

>2.here is my real code
>real code1
>require 'rubygems'
>require 'mysql'
>require 'date'
>class  Analyse
>  @@result=[]

You're still using a class variable rather than an instance variable.
You should understand the difference between the two.  Try this
explanation:
<http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/>

I would suggest replacing that line with:

def initialize
  @result = []
end

This will instantiate and initialize an instance variable that you can
use to collect the results.  Then change all references to "@@result"
to "@result".

>  def self.vol(symbol,cycle)

Change this to "def vol(symbol,cycle)" to make it an instance method
instead of a class method.

>  cycle=cycle.to_i
>  dbh = Mysql.real_connect("localhost", "root", "******")
>  dbh.query("use  stock;")
>  result=dbh.query("select symbol,date,open,high,low,close  from 
>`#{symbol}` order by date asc;")
>  compute=[]
>  result.each{|row|   compute<<row.join(";")}

Why are you joining the values here only to split them up in the block
passed to each?  The result should be a two dimensional array, which
you could index into easily.

>  compute.each.with_index{|row,idx|
>  row=row.split(";")

You're reusing a variable name here.  While scope may prevent
collisions with the variable of the same name in the outer loop, it's
still a bad idea because it's confusing to someone reading your code
(including a future you).  Instead of "row" try "fields" or something
for the inner loop.

>  if idx> cycle-2  then
>    if  row[4].to_f==0  then
>      row[6]="nil"

Do you really mean to assign a string containing the characters "n",
"i" and "l" to row[6]?  The call to to_f in the mean method will
return 0.0 for that, the same as if you had set row[6] = nil.

>    else
>      mymax=[]
>      mymin=[]
>      for  i  in  idx-cycle+1..idx
>        mymax<<compute[i].split(";")[3].to_f
>        mymin<<compute[i].split(";")[4].to_f
>      end
>      max=mymax.max
>      min=mymin.min
>      row[6]=format("%.2f",100*(max-min)/min)
>    end
>  else
>    row[6]="nil"
>  end
>     @@result<<row.join(";")
>   }
>   end
>
>def mean
>  amean=[]
>   @@result.each{|line|
>        line.each{|item|
>        amean<< item.chomp.split(";")[-1].to_f
>       }}
>     amean=amean.compact
>     format("%.2f",amean.inject(0){|s,n| s+n}/(amean.size.to_f)).to_f
>end
>end

[snip]

>2)i want  to make  Analyse.vol("c","5").mean  run
>real code1 can get :
>NoMethodError: undefined method `mean' for nil:NilClass

[snip rest]

You're trying to mix instance methods and class methods in a way that
won't work.  You really need to understand the difference between the
two concepts.

If you convert everything to instance methods and variables, then you
can have each of these functions return self, allowing chaining.
Example:

demo.rb
-------
class A
  def initialize
    clear
  end
  
  def clear
    @result = []
    return self
  end
  
  def foo
    10.times { @result << rand(1000) }
    return self
  end
  
  def bar
    @result.each { |item| puts item }
    return self
  end
end

C:\temp>irb
irb(main):001:0> require 'demo'
=> true
irb(main):002:0> a = A.new
=> #<A:0x2df8c88 @result=[]>
irb(main):003:0> a.foo
=> #<A:0x2df8c88 @result=[154, 851, 93, 136, 183, 90, 34, 175, 345, 185]>
irb(main):004:0> a.bar
154
851
93
136
183
90
34
175
345
185
=> #<A:0x2df8c88 @result=[154, 851, 93, 136, 183, 90, 34, 175, 345, 185]>
irb(main):005:0> a.clear
=> #<A:0x2df8c88 @result=[]>
irb(main):006:0> a.foo.bar
9
878
775
994
876
60
917
29
39
610
=> #<A:0x2df8c88 @result=[9, 878, 775, 994, 876, 60, 917, 29, 39, 610]>
irb(main):007:0> a.clear.foo.bar
366
247
704
920
587
201
861
644
771
769
=> #<A:0x2df8c88 @result=[366, 247, 704, 920, 587, 201, 861, 644, 771, 769]>
irb(main):008:0>

-- 
Charles Calvert
Moderator - alt.computer.consultants.moderated
Submission Address: accm / celticwolf.net
Contact Address: accm_mod / celticwolf.net