[#8566] Visions for 2001/1.7.x development? — Robert Feldt <feldt@...>

Hi matz and other Ruby developers,

18 messages 2001/01/03
[#8645] Re: Visions for 2001/1.7.x development? — matz@... (Yukihiro Matsumoto) 2001/01/04

Hi,

[#8580] bug?? — jmichel@... (Jean Michel)

I don't understand the following behaviour:

19 messages 2001/01/03

[#8633] Interesting Language performance comparisons - Ruby, OCAML etc — "g forever" <g24ever@...>

13 messages 2001/01/04

[#8774] No :<, :>, etc. methods for Array — "Brian F. Feldman" <green@...>

So, why not include Comparable in Array by default? It shouldn't have any

28 messages 2001/01/07
[#8779] Re: No :<, :>, etc. methods for Array — matz@... (Yukihiro Matsumoto) 2001/01/07

Hi,

[#8780] Re: No :<, :>, etc. methods for Array — "Brian F. Feldman" <green@...> 2001/01/07

matz@zetabits.com (Yukihiro Matsumoto) wrote:

[#8781] Re: No :<, :>, etc. methods for Array — gotoken@... (GOTO Kentaro) 2001/01/07

In message "[ruby-talk:8780] Re: No :<, :>, etc. methods for Array"

[#8782] Re: No :<, :>, etc. methods for Array — "Brian F. Feldman" <green@...> 2001/01/07

gotoken@math.sci.hokudai.ac.jp (GOTO Kentaro) wrote:

[#8829] Sandbox (again) — wys@... (Clemens Wyss)

Hi,

20 messages 2001/01/08
[#8864] Re: Sandbox (again) — Clemens Hintze <c.hintze@...> 2001/01/08

On 8 Jan, Clemens Wyss wrote:

[#8931] String confusion — Anders Bengtsson <ndrsbngtssn@...>

Hello everyone,

21 messages 2001/01/09
[#8937] Re: String confusion — matz@... (Yukihiro Matsumoto) 2001/01/09

Hi,

[#8953] Please remove account from files — "Thomas Daniels" <westernporter@...>

Please take my e-mail address from your files and "CANCEL" my =

14 messages 2001/01/09
[#8983] Re: Please remove account from files — John Rubinubi <rubinubi@...> 2001/01/10

On Wed, 10 Jan 2001, Thomas Daniels wrote:

[#9020] time to divide -talk? (was: Please remove account from files) — Yasushi Shoji <yashi@...> 2001/01/10

At Wed, 10 Jan 2001 14:23:30 +0900,

[#9047] Re: time to divide -talk? (was: Please remov e account from files) — Aleksi Niemel<aleksi.niemela@...>

Yasushi Shoji:

27 messages 2001/01/10
[#9049] Re: time to divide -talk? — Yasushi Shoji <yashi@...> 2001/01/10

At Thu, 11 Jan 2001 00:20:45 +0900,

[#9153] what about this begin? — Anders Strandl Elkj誡 <ase@...> 2001/01/11

[#9195] Re: Redefining singleton methods — ts <decoux@...>

>>>>> "H" == Horst Duch=EAne?= <iso-8859-1> writes:

10 messages 2001/01/12

[#9242] polymorphism — Maurice Szmurlo <maurice@...>

hello

73 messages 2001/01/13

[#9279] Can ruby replace php? — Jim Freeze <jim@...>

When I read that ruby could be used to replace PHP I got really

15 messages 2001/01/14

[#9411] The Ruby Way — "Conrad Schneiker" <schneiker@...>

As a member of the "Big 8" newsgroups, "The Ruby Way" (of posting) is to

15 messages 2001/01/17

[#9462] Re: reading an entire file as a string — ts <decoux@...>

>>>>> "R" == Raja S <raja@cs.indiana.edu> writes:

35 messages 2001/01/17
[#9465] Re: reading an entire file as a string — Dave Thomas <Dave@...> 2001/01/17

raja@cs.indiana.edu (Raja S.) writes:

[#9521] Larry Wall INterview — ianm74@...

Larry was interviewed at the Perl/Ruby conference in Koyoto:

20 messages 2001/01/18
[#10583] Re: Larry Wall INterview — "greg strockbine" <gstrock@...> 2001/02/08

Larry Wall's interview is how I found out

[#9610] Re: 101 Misconceptions About Dynamic Languages — "Ben Tilly" <ben_tilly@...>

"Christian" <christians@syd.microforte.com.au> wrote:

13 messages 2001/01/20

[#9761] Re: 101 Misconceptions About Dynamic Languages — ts <decoux@...>

>>>>> "C" == Christoph Rippel <crippel@primenet.com> writes:

16 messages 2001/01/23

[#9792] Ruby 162 installer available — Dave Thomas <Dave@...>

15 messages 2001/01/24

[#9958] Re: Vim syntax files again. — "Conrad Schneiker" <schneik@...>

Hugh Sasse wrote:

14 messages 2001/01/26
[#10065] Re: Vim syntax files again. — Hugh Sasse Staff Elec Eng <hgs@...> 2001/01/29

On Sat, 27 Jan 2001, Conrad Schneiker wrote:

[#9975] line continuation — "David Ruby" <ruby_david@...>

can a ruby statement break into multiple lines?

18 messages 2001/01/27
[#9976] Re: line continuation — Michael Neumann <neumann@...> 2001/01/27

On Sat, 27 Jan 2001, David Ruby wrote:

[#9988] Re: line continuation — harryo@... (Harry Ohlsen) 2001/01/28

>A statement break into mutliple lines if it is not complete,

[ruby-talk:8451] Re: string like istringstream (was: A bug inruby)

From: jmichel@... (Jean Michel)
Date: 2001-01-01 01:40:01 UTC
List: ruby-talk #8451
In article <0G6G004FFIMJ0S@mta5.snfc21.pbi.net>,
Kevin Smith  <sent@qualitycode.com> wrote:
>jmichel@schur.institut.math.jussieu.fr wrote:
>>point. But, since my last post, further thought has led me to a solution
>>(if you like it it can be in the  FAQ, Dave). The API from IO that I use
>>is just  for now .read  and .seek  but I may  want to use  other methods
>>eventually. The solution to share code is
>>
>> 1- Derive a class from String that  has methods .read and .seek . I say
>> derive a  class because  I need  to add  an instance  variable 'current
>> pointer' and it  seems cleaner to have  this in a new  class. But since
>> instance  variables can  magically appear  maybe  I need  not derive  a
>> class. I can just do:
>
>Perfect. And I agree that it should be a distinct 
>class. I would propose IOString as the name. 
>
>Perhaps we persuade you to contribute what you 
>end up with to the RAA (Ruby App Archive) so 
>others can benefit from it, and extend it.

Well, below is  my code. It is  a kind of 'minimal' solution:  I did not
derive a different  class from string, and  I did not even  add a method
as_file since .rewind  does the job. Also I have  yet implemented only a
small subset of the ID3V2 standard, but which covers all the music files
I have on  my hard disk. At  the bottom is a sample  application where I
run over all  .mp3 files in a  directory, show the ID3v1  and ID3v2 tags
and propose  to rename the  file to trak_no+title.mp3 (I  follow windows
filename conventions, I work under  windows with djgpp). Any comments on
how to shorten or rubify my code are welcome.

class String
  def rewind
    @current_pointer=0
  end
  def read(n)
    @current_pointer+=n
    if @current_pointer>=length
       @current_pointer=length
       nil
    else
      self[@current_pointer-n..@current_pointer-1]
    end
  end
  def seek(n,where)
    case where
      when IO::SEEK_CUR
         @current_pointer+=n
      when IO::SEEK_END
         @current_pointer=length+n
      when IO::SEEK_SET
         @current_pointer=n
    end
    0
  end
  def show
    gsub(/[\000-\037]/,sprintf('\\\\%03o',$0.to_i))
  end
end

class ID3V2tag
  attr_accessor(:size,:pad,:version,:revision,:flags,:frames)
  def to_s
    res="ID3V2."+@version.to_s+"."+@revision.to_s
    @flags.each_byte { |fl,i|
       if fl==?1 
	res<<"["<<%w[Unsynchronisation Extended_Header Experimental_indicator
	  Footer_present Unknown4 Unknown5 Unknown6 Unknown7][i]<<"]"
       end}
    res+=" Size="+@size.to_s+" Padding="+pad.to_s+"\n"
    res<<@frames.map{|x| x.to_s}.join("\n")
    res
  end
  def [](tag)
    @frames.detect{|f| f.header==tag}
  end
end

class ID3V2Frame
  attr_accessor(:header,:size,:flags,:data,:encoding)
  def to_s
    desc={"TRCK"=>"Track/Elts", "TMED"=>"Media Type", "TCON"=>"Content Type",
          "TALB"=>"Album Title", "TPE1" =>"Lead Artist", "TIT2"=>"Title",
	  "TYER"=>"Year", "COMM"=>"Comment", "TLEN"=>"Length", "TFLT"=>"Type"}
    desc.default="??"
    h="["+@header+"]"+desc[@header]
    e=case @encoding
      when 0 then ""  # ISO-8859-1 (default)
      when 1 then "[UTF-16]"
      when 2 then "[UTF-16BE]"
      when 3 then "[UTF-8]"
      else "[UNKNOWN]"
    end
    case @header
      when "COMM" 
        sprintf("%-20s<%s>",h+e+"["+@data[0..2].show+"]",@data[3..@size-2].show)
      when /T.../ then 
	res=sprintf("%-20s<%s>",h+e,@data.show)
	if @header=="TLEN" 
	  res+=sprintf("=%.3f sec.",@data.to_i/1000.0)
	elsif @header=="TFLT"
	  res+="="+{ "MPG"=>"MPEG_Audio", 
	  "/1"=>"MPEG_1/2_layerI", "/2"=>"MPEG_1/2_layerII",
	  "/3"=>"MPEG_1/2_layerIII", "/2.5"=>"MPEG_2.5",
	  "/AAC"=>"Advanced_audio_compression ",
	  "VQF"=>"Transform-domain_weighted_interleave_vector_quantisation",
	  "PCM"=>"Pulse_code_modulated_audio"}[@data]
	end
	res
      else h.ljust(20)+"<"+@data.show+">"
    end
  end
end
    
module ReadID3tag
  def read_synchsafe_i
    res=0
    read(4).unpack("C4").each { |b| res=128*res+b}
    res
  end

  def read_frame
    res=ID3V2Frame.new
    res.header=read(4)
    if res.header[0]==0
      seek(-4,IO::SEEK_CUR)
      return nil
    end
    res.size=read_synchsafe_i
    res.flags=read(2).unpack("B8B8").join
    res.data=read(res.size)
    case res.header
      when /(T...)|(COMM)/ then res.encoding=res.data.slice!(0)
    end
    res
  end

  def read_ID3V2_tag
    rewind
    if read(3)!="ID3" then return nil end
    res=ID3V2tag.new
    res.version,res.revision,res.flags=read(3).unpack("CCB8")
    res.frames=[]
    res.pad=res.size=read_synchsafe_i
    while res.pad>=10 and (fr=read_frame)
      if res.pad<fr.size+10 then raise "Wrong Frame" end
      res.pad-=fr.size+10
      res.frames<<fr
    end
    read(res.pad).each_byte{|i| if i!=0 then raise "non null byte at end" end}
    return res
  end

  def read_ID3V1_tag
    seek(-128,IO::SEEK_END)
    tag,title,artist,album,year,comment,track,genre=
                         read(128).unpack("Z3Z30Z30Z30Z4Z28xC1C1")
    if tag!="TAG"
      nil
    else
      "ID3V1\nTitle=<"+title.show+">\nArtist=<"+artist.show+">\nAlbum=<"+
      album.show+">\nYear="+year.show+"\nComment=<"+comment.show+
	  ">\nTrack="+track.to_s+"\nGenre="+genre.to_s+"\n"
    end
  end
end

class IO
  include ReadID3tag
end

class String
  include ReadID3tag
end

Dir["*.mp3"].each{ |f| print "\n{",f,"}\n"
  tag=open(f,"rb"){ |fl| print fl.read_ID3V1_tag; fl.read_ID3V2_tag}
  print tag,"\n"
  if tr=tag["TRCK"] then
    newname=sprintf("%02d-%s.mp3",tr.data.to_i,tag["TIT2"].data.tr(
       " :`\"\\/*?|","_;''--#_-"))
    print "propose rename (y/n/q) to\n",newname
    case gets
      when "q\n" then break 
      when "n\n" then next
      when "y\n" then File.rename(f,newname)
      else raise "should answer q,n or y"
    end
  end
}

In This Thread